http://acm.hdu.edu.cn/showproblem.php?pid=3535
题意:有n组工作,T时间,每个工作组中有m个工作,改组分类是s,s是0是组内至少要做一件,是1时最多做一件,2时随意,每项工作的描述是花费的时间和获得的快乐值,求在T时间内可获的最大快乐值。
memset放错位置了,折腾老半天。
分组混合背包,有的取一件或不取,有的随意,有的最少一个
分三种情况讨论
s==0 考虑前面取过时这次取或不取,前一组取过时这次取或不取
s==1 考虑前一组取过时这次取或不取
s==2 考虑前面取过时这次取或不取
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,t,m,s; int time[105],happy[105],dp[105][105]; int max(int a,int b) { return a>b?a:b; } int main() { int i,j,k; while(cin>>n>>t) { memset(dp,-1,sizeof(dp)); memset(dp[0],0,sizeof(dp[0])); for(i=1;i<=n;i++) { scanf("%d %d",&m,&s); for(j=0;j<m;j++) { scanf("%d%d",&time[j],&happy[j]); } if(s==0) { for(k=0;k<m;k++) { for(j=t;j>=time[k];j--) { if(dp[i][j-time[k]]!=-1) dp[i][j]=max(dp[i][j],dp[i][j-time[k]]+happy[k]); if(dp[i-1][j-time[k]]!=-1) dp[i][j]=max(dp[i][j],dp[i-1][j-time[k]]+happy[k]); } } } else if(s==1) { for(j=0;j<=t;j++) dp[i][j]=dp[i-1][j]; for(k=0;k<m;k++) { for(j=t;j>=time[k];j--) { if(dp[i-1][j-time[k]]!=-1) dp[i][j]=max(dp[i][j],dp[i-1][j-time[k]]+happy[k]); } } } else { for(j=0;j<=t;j++) dp[i][j]=dp[i-1][j]; for(k=0;k<m;k++) { for(j=t;j>=time[k];j--) { if(dp[i][j-time[k]]!=-1) dp[i][j]=max(dp[i][j],dp[i][j-time[k]]+happy[k]); } } } } printf("%d ",dp[n][t]); } return 0; }