这题我打的真的是千辛万苦啊!!!
先打了个贪心,呵呵WA50。。。
然后知道有一个五维DP的方法(真的是简单易懂)
设f[i][j][k][l][v]表示
第一个还剩i个
第二个还剩j个
第三个还剩k个
第四个还剩l个
第五个还剩v个
看看吧,真多啊
接着暴力转移n个(记得判一下能否转移)
每次转移的时候都看看将它剩下的全部单价购买后的价钱能否影响ans
#include<cstdio>
#include<cstring>
#include<algorithm>
#define minn(x,y) x=x<y ? x:y
#define fd f[d[1]][d[2]][d[3]][d[4]][d[5]]
using namespace std;
int n,m,a[101],b[101][6][2],d[6],e[6];
int fr[1001],c[101],nd[6],sl[6],ans=66666666;
int f[6][6][6][6][6];
bool bz;
inline int read()
{
int x=0; char c=getchar();
while (c<'0' || c>'9') c=getchar();
while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x;
}
int main()
{
freopen("shop.in","r",stdin);
// freopen("shop.out","w",stdout);
n=read();
for (int i=1;i<=n;i++)
{
a[i]=read();
for (int j=1;j<=a[i];j++)
b[i][j][0]=read(),b[i][j][1]=read();
c[i]=read();
}
m=read();
for (int i=1;i<=m;i++)
fr[read()]=i,nd[i]=read(),sl[i]=read();
for (int i=1;i<=n;i++)
for (int j=1;j<=a[i];j++)
b[i][j][0]=fr[b[i][j][0]];
memset(f,5,sizeof(f));
f[nd[1]][nd[2]][nd[3]][nd[4]][nd[5]]=0;
for (d[1]=nd[1];d[1]>=0;d[1]--)
for (d[2]=nd[2];d[2]>=0;d[2]--)
for (d[3]=nd[3];d[3]>=0;d[3]--)
for (d[4]=nd[4];d[4]>=0;d[4]--)
for (d[5]=nd[5];d[5]>=0;d[5]--)
{
for (int w=1;w<=n;w++)
{
bz=1;
memcpy(e,d,sizeof(d));
for (int o=1;o<=a[w];o++)
if (e[b[w][o][0]]<b[w][o][1]) {bz=0; break;}
else e[b[w][o][0]]-=b[w][o][1];
if (!bz) continue;
minn(f[e[1]][e[2]][e[3]][e[4]][e[5]],fd+c[w]);
}
ans=min(ans,fd+d[1]*sl[1]+d[2]*sl[2]+d[3]*sl[3]+d[4]*sl[4]+d[5]*sl[5]);
}
printf("%d
",ans);
return 0;
}