HDU3535 AreYouBusy

 1 #include<iostream>

 2 using namespace std;

 3 int Max(int a,int b,int c){

 4     if(a<b) a=b;

 5     if(a<c) a=c;

 6     return a; 

 7 }

 8 int f[105][105];

 9 int main()

10 {

11     int n,T,i,j,k,m,s,c,g;

12     while(~scanf("%d%d",&n,&T)){

13         memset(f,0,sizeof(f));

14         for(i=1;i<=n;i++){

15             scanf("%d%d",&m,&s);

16             for(j=0;j<=T;j++)

17                 f[i][j]=s?f[i-1][j]:INT_MIN;  //如果 s==0 需赋值为无穷小,

18                 //这样才能保证至少使用一次 ,因为一件也不使用对应结果就为负无穷,

19                 // s!=0时,要先传递f[i-1][j]的值给f[i][j] 

20             for(j=1;j<=m;j++){

21                 scanf("%d%d",&c,&g);

22                 for(k=T;k>=c;k--){ //递推顺序不能颠倒,因为每种工作只能被完成一次

23                                 //如 01背包中的滚动数组 

24                     if(s==1) f[i][k]=max(f[i][k],f[i-1][k-c]+g);  //01背包模型最多能选取一件 

25                     else f[i][k]=Max(f[i][k],f[i-1][k-c]+g,f[i][k-c]+g); //可以选取多件,

26                     //所以在 max中多加了了一个 f[i][k-c]+g 以致可以选取多个 

27                 }

28             }

29         }

30         printf("%d\n",max(f[n][T],-1)); //假如不存在解,f[n][T]则为负无穷 

31     }

32     return 0;

33 } 

一种混合+组合背包问题!很经典

你可能感兴趣的:(HDU)