| 
	
	
		
			  /**//* 
  题意:给出n个物品,其中有一些必买,有v1,v2容量的背包2个  求最大价值 
  还有可以免费选一个 
  如果不是免费选一个的话 
  dp0[j,k]表示不一定买的物品装在[j,k]容量的背包的最大价值 
  dp1[j,k]表示必买的物品装在[j,k]容量的背包的最大价值 
  然后二维背包即可 
  最后答案就是max{dp1[j,k]+dp0[v1-j,v2-k]}   需dp1[j,k]=total(必买物品价值总和) 
  
  但现在多了个免费的物品 
  可以加状态!方便做很多! 
  _dp0[j,k]表示不一定买的物品装在[j,k]容量的背包的最大价值,同时里面有一个免费物品 
  _dp1[j,k]表示必买的物品装在[j,k]容量的背包的最大价值,同时里面有一个免费物品 
  最后答案就是max{dp1[j,k]+_dp0[v1-j,v2-k],_dp1[j,k]+dp0[v1-j,v2-k]} 
  */ 
  #include<cstdio> 
  #include<algorithm> 
  #include<cstring> 
  
  using namespace std; 
  
  struct Gift 
    { 
  int p,h,s; 
  bool operator<(const Gift&B)const 
     { 
  return s<B.s; 
  } 
  }gift[305]; 
  
  int _dp0[505][55],dp0[505][55]; 
  int _dp1[505][55],dp1[505][55]; 
  
  int main() 
    { 
  //freopen("in","r",stdin); 
  int n,v1,v2,t=1; 
  while(scanf("%d%d%d",&v1,&v2,&n),n) 
     { 
  for(int i=0;i<n;i++) 
  scanf("%d%d%d",&gift[i].p,&gift[i].h,&gift[i].s); 
  sort(gift,gift+n); 
  
  memset(_dp0,0,sizeof(_dp0)); 
  memset(dp0,0,sizeof(dp0)); 
  memset(_dp1,0,sizeof(_dp1)); 
  memset(dp1,0,sizeof(dp1)); 
  
  //0 
  int num=0; 
  for(int i=0;i<n&&gift[i].s==0;i++,num++) 
     { 
  int p=gift[i].p,h=gift[i].h; 
  for(int j=v1;j>=0;j--) 
  for(int k=v2;k>=0;k--) 
     { 
  _dp0[j][k]=max(_dp0[j][k],dp0[j][k]+h); 
  if(k>=p) 
     { 
  dp0[j][k]=max(dp0[j][k],dp0[j][k-p]+h); 
  _dp0[j][k]=max(_dp0[j][k],_dp0[j][k-p]+h); 
  } 
  if(j>=p) 
     { 
  dp0[j][k]=max(dp0[j][k],dp0[j-p][k]+h); 
  _dp0[j][k]=max(_dp0[j][k],_dp0[j-p][k]+h); 
  } 
  } 
  } 
  
  int total = 0; 
  //1 
  for(int i=num;i<n;i++) 
     { 
  int p=gift[i].p,h=gift[i].h; 
  total+=h; 
  for(int j=v1;j>=0;j--) 
  for(int k=v2;k>=0;k--) 
     { 
  _dp1[j][k]=max(_dp1[j][k],dp1[j][k]+h); 
  if(k>=p) 
     { 
  dp1[j][k]=max(dp1[j][k],dp1[j][k-p]+h); 
  _dp1[j][k]=max(_dp1[j][k],_dp1[j][k-p]+h); 
  } 
  if(j>=p) 
     { 
  dp1[j][k]=max(dp1[j][k],dp1[j-p][k]+h); 
  _dp1[j][k]=max(_dp1[j][k],_dp1[j-p][k]+h); 
  } 
  } 
  } 
  int ans = -1; 
  for(int j=0;j<=v1;j++) 
  for(int k=0;k<=v2;k++) 
     { 
  if(dp1[j][k]==total) 
     { 
  ans = max(dp1[j][k]+_dp0[v1-j][v2-k],ans); 
  } 
  if(_dp1[j][k]==total) 
     { 
  ans = max(_dp1[j][k]+dp0[v1-j][v2-k],ans); 
  } 
  } 
  printf("Case %d: %d\n\n",t++,ans); 
  } 
  return 0; 
  }     |