Great Equipment
DP
滚动数组
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
typedef long long ll;
const int mod=1e9+7;
const int maxn=505;
int w[4],s[4],d[4];
struct node{
int x,y,z;
};
int dp[maxn][maxn];
vector<node>v[maxn];//预处理出每个背包装A、B、C的各方案
int main(){
int n;
int cnt=0;
while(cin>>n&&n){
if(cnt) cout<<endl;
cnt++;
for(int i=1;i<=3;i++){
cin>>w[i]>>s[i]>>d[i];
}
int c1,c2,c3,dd;
cin>>c1>>c2>>c3>>dd;
for(int i=1;i<=n;i++){
int cw,cs;
cin>>cw>>cs;
v[i].clear();
for(int j=0;j*w[1]<=cw&&j*s[1]<=cs;j++){
for(int k=0;k*w[2]<=cw-j*w[1]&&k*s[2]<=cs-j*s[1];k++){
for(int p=0;p*w[3]<=cw-j*w[1]-k*w[2]&&p*s[3]<=cs-j*s[1]-k*s[2];p++){
if(j==0&&k==0&&p==0) continue;//可节省时间
v[i].push_back({j,k,p});
}
}
}
}
memset(dp,-INF,sizeof(dp));//需初始化为负数,初始化为0会WA
dp[0][0]=0;
for(int i=1;i<=n;i++){
for(int j=500;j>=0;j--){
for(int k=500;k>=0;k--){
int mmax=-INF;
for(int p=0;p<v[i].size();p++){//枚举各可能方案
if(j>=v[i][p].x&&k>=v[i][p].y){
mmax=max(mmax,dp[j-v[i][p].x][k-v[i][p].y]+v[i][p].z);
}
}
dp[j][k]=max(dp[j][k],mmax);
}
}
}
int ans=0;
for(int i=0;i<=500;i++){
for(int j=0;j<=500;j++){
if(dp[i][j]<0) continue;
ans=max(ans,i*d[1]+j*d[2]+dp[i][j]*d[3]);//不进行组合操作
int mmin=INF;//能组合出多少套
if(c1>0) mmin=min(mmin,i/c1);
if(c2>0) mmin=min(mmin,j/c2);
if(c3>0) mmin=min(mmin,dp[i][j]/c3);
ans=max(ans,mmin*dd+(i-mmin*c1)*d[1]+(j-mmin*c2)*d[2]+(dp[i][j]-mmin*c3)*d[3]); //进行组合操作
}
}
cout<<"Case "<<cnt<<": "<<ans<<endl;
}
return 0;
}