HDU 3033 I love sneakers! 分组背包+约束限制(每组至少取一个)。
来源:互联网 发布:vc高级编程 编辑:程序博客网 时间:2024/06/05 23:06
注意至少取一个,仔细分析一下,此时光靠一个一维数组是不可以完成状态转移的,必须用二维数组或两个一维数组(滚动数组)。
建议多用二维数组,二维数组比较好理解,不容易出错,除非数据量太大,二维开不下。当然,如果对状态转移理解的比较深刻可以尝试着写成滚动数组。
先讲一讲二维数组的做法:
dp[i][j]表示进行到了第i组容量为j所装载的最大价值。
则dp[i][j]这个状态必须从dp[i-1][j-w[x]]+p[x] (选了第1个第i组的物品),dp[i][j-w[x]]+p[x](已经选过第i组的物品,这次又选了第i组的物品),dp[i][j](不选这个物品);
所以状态转移方程为:
dp[i][j]=max(dp[i][j],max(dp[i][j-w[x]]+p[x],dp[i-1][j-w[x]]+p[x]));
二维数组版:
View Code
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define INF 1<<29int n, m, k;int w[101],p[101],z[101];int dp[12][10003];int main(){ int i, j, x; while(~scanf("%d%d%d",&n,&m,&k)) { for(i=1;i<=n;i++) scanf("%d%d%d",&z[i],&w[i],&p[i]); for(j=0;j<=m;j++)dp[0][j]=0;//最开始层赋0 for(i=1;i<=k;i++) //其它层赋值-INF for(j=0;j<=m dp[i][j]=-INF; for(i=1;i<=k;i++) for(x=1;x<=n;x++) for(j=m;j>=0;j--) if(z[x]==i) if(j>=w[x]) dp[i][j]=max(dp[i][j],max(dp[i][j-w[x]]+p[x],dp[i-1][j-w[x]]+p[x])); // 如果要写成把2个比较拆开来写的 请注意: //下面两个顺序不能换,如果换了,当出现w[x]==0时,会加2次。 //dp[i][j]=max(dp[i][j],dp[i][j-w[x]]+p[x]); //dp[i][j]=max(dp[i][j],dp[i-1][j-w[x]]+p[x]); if(dp[k][m]<0)printf("Impossible\n"); else printf("%d\n",dp[k][m]); } return 0;}
滚动数组版1
View Code
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define INF 1<<29int n, m, k;int w[101],p[101],z[101];int dp[10003],tmp[10003];int main(){ int i, j, x; while(~scanf("%d%d%d",&n,&m,&k)) { for(i=1;i<=n;i++) scanf("%d%d%d",&z[i],&w[i],&p[i]); memset(dp,0,sizeof(dp)); for(i=1;i<=k;i++) { for(j=m;j>=0;j--) //每次状态转移前 { tmp[j]=dp[j]; //将讲前一轮的状态转移到tmp[] dp[j]=-INF; //当前的状态dp[]初始化 } for(x=1;x<=n;x++) for(j=m;j>=0;j--) if(z[x]==i) if(j>=w[x]) dp[j]=max(dp[j],max(dp[j-w[x]]+p[x],tmp[j-w[x]]+p[x])); } if(dp[m]<0)printf("Impossible\n"); else printf("%d\n",dp[m]); } return 0;}
滚动数组版2:
View Code
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define inf 1<<29int n, sum, m;int dp[10003];int z[101], w[101], p[101];int main(){ int i, j, k; while( ~scanf("%d%d%d", &n, &sum, &m) ) { for(i = 1; i <= n; i++) scanf("%d%d%d", &z[i], &w[i], &p[i]); int g1 = 0, g2 = 1; for(i = 0; i <= sum; i++) dp[g1][i] = 0; for(k = 1; k <= m; k++) { for(j = 0; j <= sum; j++) dp[g2][i] = -inf; for(j = sum; j >= 0; j--) for(i = 1; i <= n; i++) if(z[i] == k) { if(w[i] <= j) dp[g2][j] = max( dp[g2][j], max ( dp[g2][j - w[i]] + p[i], dp[g1][j - w[i]] + p[i] ) ); } g1 = !g1; g2 = !g2; } printf("%d\n", dp[g1][sum]); } return 0;}
- HDU 3033 I love sneakers! 分组背包+约束限制(每组至少取一个)。
- HDU 3033 I love sneakers! 每组最至少取一个的分组背包
- hdu 3033 I love sneakers! 分组背包之每组至少取一个
- hdu 3033 I love sneakers!(分组背包,每组至少取1个)
- hdu 3033 I love sneakers!(分组背包,每组至少取一件)
- HDU 3033 I love sneakers! (分组背包 每组至少选一个)
- hdu3033I love sneakers!【分组背包】每组至少取一个
- HDU 3033 I love sneakers!(DP 背包 每组最小取一个的背包)
- hdu 3033 I love sneakers! (多组背包变形-----每组至少选一个)
- HDU-3033 I love sneakers! (多重背包 每组至少买一个)
- HDU 3033 I love sneakers!(分组背包/至少选一个)
- HDU 3033 I love sneakers! -- 分组背包 每组最少拿一个
- I love sneakers! 分组背包(每组至少选一件)
- 动态规划--至少取一个的分组背包--hdu3033 I love sneakers!
- hdu 3033 I love sneakers! 分组背包
- HDU 3033 I love sneakers! (分组背包)
- hdu 3033 I love sneakers!(分组背包)
- hdu 3033 I love sneakers! (分组背包)
- POJ 1976 A Mini Locomotive DP
- POJ 3737 UmBasketella 三分法 入门题
- POJ 3628 Bookshelf 2 0-1背包 or DFS 水题
- 约瑟夫环的解决
- POJ 1948 Triangular Pastures 二维 0-1背包
- HDU 3033 I love sneakers! 分组背包+约束限制(每组至少取一个)。
- HDU 3535 AreYouBusy 经典混合背包
- POJ 1252 Euro Efficiency 2个完全背包
- POJ 2063 Investment 完全背包
- POJ3260 The Fewest Coins 多重背包+完全背包
- POJ 1742 Coins 多重背包入门题
- 程序员面试之道(《程序员面试笔试宝典》)之快乐编程的好习惯有哪些?
- HDU 3449 Consumer 依赖背包 入门题
- LeetCode - Distinct Subsequences