HDU 3033 I love sneakers!(分组背包/至少选一个)
2016-04-03 16:21
495 查看
题目链接:
HDU 3033 I love sneakers!
题意:
有n个物品分成k组,每个物品都有相应的价格和价值,每组物品都至少得买一件。有m元,如果能把k组每组至少买一件输出用m元能买到的最大价值;否自输出Impossible。
分析:
01背包的变形–分组背包,而且是每组至少买一个的分组背包而不是每组至多只能买一个。
用dp[i][k]表示在前i组每组至少选一样,耗费k能获得的最大价值,
初始化dp[i][k]为-1,但是dp[i][k]=0,这样是为了在购买第一组时可以从dp[0]状态中选择。
状态转移方程:
这两个if是独立的,也就是不能用else if相连,因为第一个if是判断是否在第i组中同时买第j件和之前在i组中买的;第二个if是判断是否在第i组中只买第j件
注意k的遍历顺序应该是从M–>cost[i][j]因为是滚动数组。
HDU 3033 I love sneakers!
题意:
有n个物品分成k组,每个物品都有相应的价格和价值,每组物品都至少得买一件。有m元,如果能把k组每组至少买一件输出用m元能买到的最大价值;否自输出Impossible。
分析:
01背包的变形–分组背包,而且是每组至少买一个的分组背包而不是每组至多只能买一个。
用dp[i][k]表示在前i组每组至少选一样,耗费k能获得的最大价值,
初始化dp[i][k]为-1,但是dp[i][k]=0,这样是为了在购买第一组时可以从dp[0]状态中选择。
状态转移方程:
if(dp[i][k-cost[i][j]]!=-1){//在第i组至少已经选一件商品 dp[i][k]=max(dp[i][k],dp[i][k-cost[i][j]]+val[i][j]); } if(dp[i-1][k-cost[i][j]]!=-1){//dp[i-1][k-cost[i][j]]!=-1保证前i-1组每组至少选一个 dp[i][k]=max(dp[i][k],dp[i-1][k-cost[i][j]]+val[i][j]); }
这两个if是独立的,也就是不能用else if相连,因为第一个if是判断是否在第i组中同时买第j件和之前在i组中买的;第二个if是判断是否在第i组中只买第j件
注意k的遍历顺序应该是从M–>cost[i][j]因为是滚动数组。
//109MS 2008K #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAX_N=110; const int MAX_K=15; const int MAX_M=10010; int N,M,K; int cost[MAX_K][MAX_N],val[MAX_K][MAX_N],num[MAX_K],dp[MAX_K][MAX_M]; int main() { //freopen("Din.txt","r",stdin); while(~scanf("%d%d%d",&N,&M,&K)){ memset(num,0,sizeof(num)); for(int i=0;i<N;i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); cost[a][num[a]]=b; val[a][num[a]]=c; num[a]++; } memset(dp,-1,sizeof(dp)); for(int i=0;i<MAX_M;i++) dp[0][i]=0; for(int i=1;i<=K;i++){//dp[i][k]表示在前i组每组至少选一样,耗费k能获得的最大价值 for(int j=0;j<num[i];j++){ for(int k=M;k>=cost[i][j];k--){//注意k的遍历顺序! if(dp[i][k-cost[i][j]]!=-1){//在第i组已经选一件商品 dp[i][k]=max(dp[i][k],dp[i][k-cost[i][j]]+val[i][j]); } if(dp[i-1][k-cost[i][j]]!=-1){//dp[i-1][k-cost[i][j]]!=-1保证前i-1组每组至少选一个 dp[i][k]=max(dp[i][k],dp[i-1][k-cost[i][j]]+val[i][j]); } //printf("i=%d j=%d k=%d dp[i][k]=%d\n",i,j,k,dp[i][k]); } } } if(dp[K][M]==-1) printf("Impossible\n"); else printf("%d\n",dp[K][M]); } return 0; }
相关文章推荐
- 详解Android应用中屏幕尺寸的获取及dp和px值的转换
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- LFC1.0.0 版本发布
- Android px、dp、sp之间相互转换
- HP data protector软件学习1--基本角色与基本工作流程
- HP data protector软件学习2--软件组成与界面介绍
- android中像素单位dp、px、pt、sp的比较
- Android对px和dip进行尺寸转换的方法
- 【HDU 5366】The mook jong 详解
- 【HDU 2136】Largest prime factor 详细图解
- 【HDU 1568】Fibonacci 数学公式 详解
- Android根据分辨率进行单位转换-(dp,sp转像素px)
- android 尺寸 dp,sp,px,dip,pt详解
- DP问题各种模型的状态转移方程
- HDU 1568
- HDU1290
- POJ-1695-Magazine Delivery-dp
- nyoj-1216-整理图书-dp
- TYVJ1193 括号序列解题报告