HDU 3535 AreYouBusy

该题要用分组背包做,这里就是要怎样处理0必须选,1最多选一个,2任意选的问题;

这里我们就开个二维数组;f[i][j],i表示第组,j表示时间;当该组为0时,我们在该组的选择可以来自上一组的结果,也可以来自该组的结果;

如果为1那么结果只能依赖上一组的结果,如果依赖本组那么就会造成该组会多选;

为2是那就是一个01背包;

View Code
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
class node
{
public:
int cost,happy;
};
class Node
{
public:
node t[124];
int type,N;
};
Node T[124];
int Max( int a, int b )
{
return a > b ? a : b;
}
int DP( int n , int time )
{
int f[124][124];
memset( f , -1 , sizeof( f ) );
memset( f[0] , 0 ,sizeof(f[0]) );
for( int i = 1 ; i <= n ; i ++ )
{
switch( T[i].type )
{
case 0:
for( int j = 0 ; j < T[i].N; j++ )
for( int k = time ; k >= T[i].t[j].cost ; k-- )
{
if( f[i][k-T[i].t[j].cost]!=-1 )
f[i][k] = Max(f[i][k],f[i][k-T[i].t[j].cost] + T[i].t[j].happy);
if( f[i-1][k-T[i].t[j].cost]!=-1 )
f[i][k] = Max(f[i][k],f[i-1][k-T[i].t[j].cost] + T[i].t[j].happy);

}
break;
case 1:
for( int j = 0 ; j < T[i].N; j++ )
for( int k = time ; k >= 0 ; k-- )
{
f[i][k] = Max(f[i-1][k],f[i][k]);
if( k-T[i].t[j].cost>=0&&f[i-1][k-T[i].t[j].cost] != -1 )
f[i][k] = Max( f[i][k],f[i-1][k-T[i].t[j].cost] + T[i].t[j].happy );
}
break;
case 2:
for( int j = 0 ; j <= time ; j++)
{
f[i][j] = f[i-1][j];
}
for( int j = 0 ; j < T[i].N; j++ )
for( int k = time ; k >= 0 ; k-- )
{
if( k-T[i].t[j].cost>=0&&f[i][k-T[i].t[j].cost]!=-1 )
f[i][k] = Max(f[i][k], f[i][k-T[i].t[j].cost] + T[i].t[j].happy);
}
break;
}
}
return f[n][time];
}
int main( )
{
int n , m , time, type;
while( scanf( "%d%d",&n , &time )==2 )
{
for( int i = 1 ; i <= n ; i++ )
{
scanf( "%d%d",&T[i].N, &T[i].type );
for( int j = 0 ; j < T[i].N ; j++ )
{
scanf( "%d%d",&T[i].t[j].cost , &T[i].t[j].happy );
}

}
printf("%d\n", DP( n , time ));
}
return 0;
}

 

你可能感兴趣的:(HDU)