HDOJ 3535 AreYouBusy (背包 每组至少一个)

来源:互联网 发布:我尼玛知乎 编辑:程序博客网 时间:2024/05/22 13:54

题目链接:(—_—) zZ


题目大意:有n种工作的集合, 每种集合有一种类型, 0为最少在这个集合中选一个工作, 1为最多在这个集合中选一个工作, 2为随便选, 做每个工作要花一定的时间和得到一定的幸福度, 求在t时间内获得的最大幸福度


思路:类型为0时是分组背包的变形 , 为1时就是分组背包, 为2是为0-1背包,分别根据背包类型求出就可

Ps:无限wa


code:

#include <stdio.h>#include <string.h>struct node{    int t, h;}pack[5][100002];int c = 0, n = 0, t = 0,dp[102][102], num[5][102], index1[5], ind[102];void zeropack( int in, int start)//至少选一个{    int i = 0, j = 0, k  = 0, tpval = 0;    for(i = 0; i<num[0][in]; i++)    {        for(j = t; j>=pack[0][start+i].t; j--)        {            if(dp[c][j-pack[0][start+i].t] != -1)                dp[c][j] = dp[c][j]>dp[c][j-pack[0][start+i].t]+pack[0][start+i].h? dp[c][j]:dp[c][j-pack[0][start+i].t]+pack[0][start+i].h;            if(dp[c-1][j-pack[0][start+i].t] != -1)                dp[c][j] = dp[c][j]>dp[c-1][j-pack[0][start+i].t]+pack[0][start+i].h? dp[c][j]:dp[c-1][j-pack[0][start+i].t]+pack[0][start+i].h;        }    }}void onepack(int in, int start)//最多选一个 分组背包问题{    int i = 0, j = 0, k = 0, tpval = 0;    for(i = 0; i<=t; i++)        dp[c][i] = dp[c-1][i];    for(i = t; i>=0; i--)    {        for(j = 0; j<num[1][in]; j++)            if(pack[1][start+j].t<=i && dp[c-1][i-pack[1][start+j].t] != -1)                dp[c][i] = dp[c][i]>dp[c-1][i-pack[1][start+j].t]+pack[1][start+j].h? dp[c][i]:dp[c-1][i-pack[1][start+j].t]+pack[1][start+j].h;    }}void twopack(int in, int start)//0-1背包{    int i = 0, j =0, k = 0, tpval = 0;    for(i = 0; i<=t; i++)        dp[c][i] = dp[c-1][i];    for(i = 0; i<num[2][in]; i++)    {        for(j = t; j>=pack[2][start+i].t; j--)        {            if(dp[c][j-pack[2][start+i].t] != -1 )                dp[c][j] = dp[c][j]>dp[c][j-pack[2][start+i].t]+pack[2][start+i].h? dp[c][j]:dp[c][j-pack[2][start+i].t]+pack[2][start+i].h;        }    }    c++;}int main(){    int i = 0, j = 0, m = 0, s = 0, start = 0, ans = -1;    while(scanf("%d %d", &n, &t) != EOF)    {        c = 1;        memset(index1, 0, sizeof(index1));        memset(ind, 0, sizeof(ind));        memset(dp, -1, sizeof(dp));        for(i = 0; i<=t; i++)            dp[0][i] = 0;        for(i = 0; i<n; i++)        {            scanf("%d %d", &m, &s);            num[s][index1[s]++] = m;//index1[s]表示有多少类为s的组            for(j =0; j<m; j++, ind[s]++)            {                scanf("%d", &pack[s][ind[s]].t);                scanf("%d", &pack[s][ind[s]].h);            }        }            start = 0;         for(j = 0; j<index1[0]; j++)//一共有多少组类属于0的          {          zeropack(j, start);              start += num[0][j];              c++;          }          start = 0;          for(j = 0; j<index1[1]; j++)          {              onepack(j, start);              start += num[1][j];              c++;          }          start = 0;          for(j = 0; j<index1[2]; j++)          {              twopack(j, start);              start += num[2][j];          }         printf("%d\n", dp[c-1][t]);  }    return 0;}


原创粉丝点击