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;
}
View Code