http://acm.hdu.edu.cn/showproblem.php?pid=3449
题意:
有很多个箱子,想买箱子中的物品必须先买下箱子,典型的依赖背包
dp[i][j]代表前i个箱子花费j的钱能获得的最大价值
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int Ni = 55; 6 const int Mi = 100005; 7 int dp[Ni][Mi]; 8 int main() 9 { 10 int n,m,tv,i,j,k,pi,c,w; 11 memset(dp[0],0,sizeof(dp[0])); 12 while(~scanf("%d%d",&n,&tv)) 13 { 14 for(i=1;i<=n;i++) 15 { 16 scanf("%d%d",&pi,&m); 17 for(j=0;j<pi;j++) dp[i][j]=-1; 18 for(j=tv;j>=pi;j--) dp[i][j]=dp[i-1][j-pi]; 19 for(k=0;k<m;k++) 20 { 21 scanf("%d%d",&c,&w); 22 for(j=tv;j>=c;j--) if(dp[i][j-c]!=-1) 23 dp[i][j]=max(dp[i][j],dp[i][j-c]+w); 24 } 25 for(j=tv;j>=0;j--) dp[i][j]=max(dp[i][j],dp[i-1][j]); 26 } 27 printf("%d\n",dp[n][tv]); 28 } 29 return 0; 30 }
优化到一维:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int Mi = 100005; 6 int dp[Mi]; 7 int arr[Mi]; 8 inline int max(int a,int b) {return a>b? a:b;} 9 int main() 10 { 11 int n,m,tv,i,j,k,pi,c,w; 12 while(~scanf("%d%d",&n,&tv)) 13 { 14 memset(dp,0,sizeof(dp)); 15 for(i=1;i<=n;i++) 16 { 17 scanf("%d%d",&pi,&m); 18 memcpy(arr,dp,sizeof(dp));//继承 19 for(k=0;k<m;k++) 20 { 21 scanf("%d%d",&c,&w); 22 for(j=tv-pi;j>=c;j--)//对附件进行01背包 23 { 24 arr[j]=max(arr[j],arr[j-c]+w); 25 } 26 } 27 for(j=pi;j<=tv;j++)//更新 28 dp[j]=max(dp[j],arr[j-pi]); 29 } 30 printf("%d\n",dp[tv]); 31 } 32 return 0; 33 }