题意:给出n种装载东西的信息(w,s) 3物品(w,s,d) 3种物品组合(c1,c2,c3,d)求出最大的防御值
思路:一看题目就有种背包的想法,但是此题有个信息就是如果知道三种物品的各自的数量,那么防御值就很简单的求了出来
用f[i][j][k]表示前i辆车装j第一件物品k第二件物品时 第三件物品最多能装的个数
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int n, c1, c2, c3, d4; int w[4], s[4], d[4]; int cw[105], cs[105], f[2][505][505]; int main() { int cas = 0; while(scanf("%d",&n) && n) { for(int i = 1 ; i <= 3 ; i++) scanf("%d%d%d",&w[i],&s[i],&d[i]); scanf("%d%d%d%d",&c1,&c2,&c3,&d4); for(int i = 1 ; i <= n ; i++) scanf("%d%d",&cw[i],&cs[i]); memset(f,-1,sizeof(f)); f[0][0][0] = 0; for(int i = 1 ; i <= n ; i++) { for(int j = 0 ; j <= min(cw[i]/w[1],cs[i]/s[1]) ; j++) { for(int k = 0 ; k <= min(cw[i]/w[2],cs[i]/s[2]) ; k++) { if(j*w[1]+k*w[2] > cw[i] || j*s[1]+k*s[2] > cs[i]) { break; } else { for(int p = 0 ; p < 505 ; p++) { for(int q = 0 ; q < 505 ; q++) { if(f[(i-1)%2][p][q] == -1) { continue; } else { int cmp = f[(i-1)%2][p][q]+min((cw[i]-j*w[1]-k*w[2])/w[3],(cs[i]-j*s[1]-k*s[2])/s[3]); if(f[i%2][p+j][q+k] < cmp) f[i%2][p+j][q+k] = cmp; } } } } } } } int res = -1; for(int i = 0 ; i < 505 ; i++) { for(int j = 0 ; j < 505 ; j++) { if(f[n%2][i][j] == -1) { continue; } else { if(d[1]+d[2]+d[3] >= d4) { if(res < f[n%2][i][j]*d[3]+i*d[1]+j*d[2]) res = f[n%2][i][j]*d[3]+i*d[1]+j*d[2]; } else { int con = min(f[n%2][i][j]/c3,min(i/c1,j/c2)); int ress = con*d4+(i-con*c1)*d[1]+(j-con*c2)*d[2]+(f[n%2][i][j]-con*c3)*d[3]; res = res<ress?ress:res; } } } } if(cas > 0) printf("\n"); printf("Case %d: %d\n",++cas,res); } return 0; }