<span>HDU3449 Consumer(依赖背包)</span>
参考:http://www.cnblogs.com/wuyiqi/archive/2011/11/26/2264283.html
题意:
有n个箱子,每个箱子里装有一些物品
要买这些物品就要先买这个箱子
这就符合依赖背包的条件了
要想买b就必须买a
思路:
先写二维的,dp[i][j]表示当前为第i个箱子,用j的金钱得到的最大价值
更新时由于当前层的物品需要先买掉箱子,所以先用bag的钱买掉箱子,
0-bag赋值为-1,不能去更新状态
然后bag-m范围继承上一层的0-m-bag的范围,因为花了bag的钱买了箱子
然后就是01背包了,传递也是一样
/* *********************************************** Author :devil ************************************************ */ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <cmath> #include <stdlib.h> using namespace std; typedef long long LL; const int inf=0x3f3f3f3f; const int mod=1e9+7; const int N=1e5+10; int dp[51][N]; int main() { //freopen("in.txt","r",stdin); int n,m; while(~scanf("%d%d",&n,&m)) { int bag,cnt,v,w; memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) { scanf("%d%d",&bag,&cnt); for(int j=0;j<bag;j++) dp[i][j]=-1; for(int j=bag;j<=m;j++) dp[i][j]=dp[i-1][j-bag];//继承上一层的结果,j-bag是因为一定要买箱子 for(int j=1;j<=cnt;j++) { scanf("%d%d",&w,&v); for(int k=m;k>=w;k--) if(dp[i][k-w]!=-1) dp[i][k]=max(dp[i][k],dp[i][k-w]+v); } for(int j=m;j>=0;j--) dp[i][j]=max(dp[i][j],dp[i-1][j]); } printf("%d\n",dp[n][m]); } return 0; }
然后再来一维的
dp[i]表示当前花了i的钱得到的最大价值
需要一个同样大小的tmp数组辅助更新状态
每一层先把dp数组里的值赋给tmp数组作为初值
然后用01背包方式更新tmp数组
传递时,要用tmp数组的i-bag更新dp数组的i,因为当前的箱子要买
/* *********************************************** Author :devil ************************************************ */ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <cmath> #include <stdlib.h> using namespace std; typedef long long LL; const int inf=0x3f3f3f3f; const int mod=1e9+7; const int N=1e5+10; int dp[N],tmp[N]; int main() { //freopen("in.txt","r",stdin); int n,m; while(~scanf("%d%d",&n,&m)) { int bag,cnt,v,w; memset(dp,0,sizeof(dp)); while(n--) { scanf("%d%d",&bag,&cnt); memcpy(tmp,dp,sizeof(dp));//继承上一层 while(cnt--) { scanf("%d%d",&w,&v); for(int i=m-bag;i>=w;i--) tmp[i]=max(tmp[i],tmp[i-w]+v); } for(int i=bag;i<=m;i++) dp[i]=max(dp[i],tmp[i-bag]); } printf("%d\n",dp[m]); } return 0; }