hdu3535:http://acm.hdu.edu.cn/showproblem.php?pid=3535
该题是非常全面的一道分组背包问题。其实理解了最多一个的分组背包问题,解题起来也是很简单的。但是该题卡了我3天,真让人郁闷。就是因为一个case过不了,里面的时间ci可以为0!!!测试数据中竟然有0分钟这种事情!!!
题解:
#include<iostream> #include<cstdio> #include<cstring> #include<vector> using namespace std; int dp[2][100+20]; typedef struct Job { int ci; int gi; }Job; int main() { int n,t; while(~scanf("%d%d",&n,&t)) { int s[n]; vector<Job> vjob[n]; for(int i=0;i<n;++i) { int m; scanf("%d%d",&m,&s[i]); for(int j=0;j<m;++j) { Job job; scanf("%d%d",&job.ci,&job.gi); vjob[i].push_back(job); } } memset(dp,0,sizeof(dp)); for(int i=0;i<n;++i) { memcpy(dp[1],dp[0],sizeof(dp[0])); //最少1 if(s[i]==0) { memset(dp[0],-1,sizeof(dp[0])); for(int j=0;j<vjob[i].size();++j) { for(int v=t;v>=0;--v) { int ci = vjob[i][j].ci; int gi = vjob[i][j].gi; if(v >= ci) { if(dp[0][v-ci] != -1) dp[0][v] = max(dp[0][v],dp[0][v-ci]+gi); if(dp[1][v-ci] != -1) dp[0][v] = max(dp[0][v],dp[1][v-ci]+gi); } } } } //最多1 else if(s[i]==1) { for(int v=t;v>=0;--v) { for(int j=0;j<vjob[i].size();++j) { int ci = vjob[i][j].ci; int gi = vjob[i][j].gi; if(v >= ci) { if(dp[0][v-ci] != -1 && ci != 0) { dp[0][v] = max(dp[0][v],dp[0][v-ci]+gi); } else if(ci==0 && dp[1][v] != -1) { //测试数据中竟然有0分钟这种事情!!! dp[0][v] = max(dp[0][v],dp[1][v]+gi); } } } } } //随意 else if(s[i]==2) { for(int j=0;j<vjob[i].size();++j) { for(int v=t;v>=0;--v) { int ci = vjob[i][j].ci; int gi = vjob[i][j].gi; if(v >= ci) { if(dp[0][v-ci] != -1) dp[0][v] = max(dp[0][v],dp[0][v-ci]+gi); } } } } } printf("%d\n",dp[0][t]); } return 0; }