HDU 3033 I love sneakers!(分组背包变形)

来源:互联网 发布:mysql有什么用知乎 编辑:程序博客网 时间:2024/06/06 02:11

题目链接:http://http://acm.hdu.edu.cn/showproblem.php?pid=3033

题意:

n组数据,m元钱,k种小吃

每组数据包含a,b,c    a:小吃种类   b:小吃价格   c:小吃价值

每种小吃买至少有1个

如果不能达到要求,就输出Impossible

否则就输出小吃的最大价值


思路:

这不是明显的分组背包,需要自己去变形

将同一种类的小吃归到一起

dp[ i ][ x ]代表第i种小吃容量为x的价值

转移方程就是:

dp[i][x] = max(dp[i][x],dp[i][x-p[i][j].w]+p[i][j].v)
dp[i][x] = max(dp[i][x],dp[i-1][x-p[i][j].w]+p[i][j].v)

这两个的位置不能换

当i=1,p[ i ][ j ].w=0时

如果调换顺序

dp[ i ][ x ]会被加了两次

导致答案出错,wa了好几把,就是这里错了


#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <string>using namespace std;int num[15];struct node{int v,w;}p[15][105];int dp[15][10005];int main(){int n,m,k;while(~scanf("%d%d%d",&n,&m,&k)){memset(p,0,sizeof(p));memset(num,0,sizeof(num));int a,b,c;for(int i=0;i<n;i++){scanf("%d%d%d",&a,&b,&c);p[a][num[a]].w=b;//变形为典型的分组背包形式 p[a][num[a]].v=c;num[a]++;}memset(dp,-1,sizeof(dp));memset(dp[0],0,sizeof(dp[0]));for(int i=1;i<=k;i++){for(int j=0;j<num[i];j++){for(int x=m;x>=p[i][j].w;x--){dp[i][x] = max(dp[i][x],dp[i][x-p[i][j].w]+p[i][j].v);dp[i][x] = max(dp[i][x],dp[i-1][x-p[i][j].w]+p[i][j].v);}}}if(dp[k][m]==-1) {printf("Impossible\n");continue;}printf("%d\n",dp[k][m]);}return 0;}




0 0
原创粉丝点击