很高兴,这道题刚编译成功提交就AC了。
简单的多重背包,标算估计是5、6维动规。其实可以通过6进制压成一维。判定是一个特价方式是否可行只需自己推一下就行了,很简单(对应位上的数目标不小于特价所需条件)。
代码:
#include<cstdio>
using namespace std;
int t[10],map[1000],l[10],c[120],p[120],dp[300000];
void init(){
t[0]=1;
for(int i=1;i<10;i++)t[i]=t[i-1]*6;
return;
}
bool from(int x,int y){
if(x>y)return 0;
for(int i=9;i>=0;i--){
if(x/t[i]>y/t[i])return 0;
x%=t[i],y%=t[i];
}
return 1;
}
int main(){
init();
int n,fin=0;
scanf("%d",&n);
for(int i=0;i<n;i++){
int code;
scanf("%d%d%d",&code,&l[i],&p[i]);
map[code]=i;
c[i]=t[i];
fin+=t[i]*l[i];
}
int s;
scanf("%d",&s);
for(int i=0;i<s;i++){
int x;
scanf("%d",&x);
int cur=0;
for(int j=0;j<x;j++){
int x,y;
scanf("%d%d",&x,&y);
cur+=t[map[x]]*y;
}
c[i+n]=cur;
scanf("%d",&p[i+n]);
}
s+=n,dp[0]=0;
for(int i=1;i<=fin;i++){
dp[i]=2147483647;
for(int j=0;j<s;j++)
if(from(c[j],i) && dp[i-c[j]]+p[j]<dp[i])dp[i]=dp[i-c[j]]+p[j];
}
printf("%d\n",dp[fin]);
return 0;
}