题意:表达能力不好,就不说了。 分析:算是比较简单的背包了,f[i][j][k]表示前i辆车装了j个武器1和k个武器2后还能装武器3的最多个数,再转移即可。
#include <iostream> #include <stdio.h> #include <memory.h> using namespace std; #define min(a,b) ((a)<(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b))
int f[2][510][510],w[4],s[4],d[4],x[110],y[110],n;
int main() { int i,j,k,now,pre,tem,c1,c2,c3,d4,ca=0,p,q,rew,res; int last1,last2,up1,up2; while(scanf("%d",&n)&&n) { if(ca>0) printf("\n"); for(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(i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]); memset(f,-1,sizeof(f)); f[0][0][0]=0; now=1; pre=0; last1=0; last2=0; for(i=1;i<=n;i++) { up1=last1+min(x[i]/w[1],y[i]/s[1]); // 加点小优化减少决策范围 从5000ms减到500ms if(up1>500) up1=500; up2=last2+min(x[i]/w[2],y[i]/s[2]); if(up2>500) up2=500; for(j=0;j<=up1;j++) { for(k=0;k<=up2;k++) { f[now][j][k]=-1; for(p=0;p<=j;p++) { if(p*w[1]>x[i]||p*s[1]>y[i]) break; for(q=0;q<=k;q++) { if(p*w[1]+q*w[2]>x[i]||p*s[1]+q*s[2]>y[i]) break; if(f[pre][j-p][k-q]==-1) continue; rew=x[i]-p*w[1]-q*w[2]; res=y[i]-p*s[1]-q*s[2]; tem=min(rew/w[3],res/s[3]); // 当前这辆车装完p个武器1和q个武器2后还能装武器3的个数 if(f[pre][j-p][k-q]+tem>f[now][j][k]) f[now][j][k]=f[pre][j-p][k-q]+tem; } } if(f[now][j][k]!=-1) { last1=max(last1,j); last2=max(last2,k); } } } tem=now; now=pre; pre=tem; } int flag,ans=0,num; if(c1*d[1]+c2*d[2]+c3*d[3]>d4) flag=1; // 选择比较好的组合武器的方式 else flag=2; for(i=0;i<=500;i++) { for(j=0;j<=500;j++) { if(f[pre][i][j]==-1) continue; k=f[pre][i][j]; if(flag==1) ans=max(ans,i*d[1]+j*d[2]+k*d[3]); else { num=min(i/c1,min(j/c2,k/c3)); tem=num*d4+(i-num*c1)*d[1]+(j-num*c2)*d[2]+(k-num*c3)*d[3]; ans=max(ans,tem); } } } printf("Case %d: %d\n",++ca,ans); } return 0; }
|
|
常用链接
留言簿
随笔分类
随笔档案
搜索
最新评论
阅读排行榜
评论排行榜
|
|