表示到第i种钱币 , 第一个人剩多少 , 第二个人剩多少 , 第三个人减一下就出来了
表示第i个人的第j种前有多少张
表示第i种钱的价值
其中
我们枚举x1 , y1,如果合法就转移
#include<bits/stdc++.h>
#define N 1050
#define M 10
using namespace std;
int X1,X2,X3,tot,cnt[M],Sum[N];
int Num[M][M],val[M]={0,100,50,20,10,5,1};
int f[M][N][N],inf,ans;
int main(){
scanf("%d%d%d",&X1,&X2,&X3);
for(int i=1;i<=3;i++){
for(int j=1;j<=6;j++){
scanf("%d",&Num[i][j]);
Sum[i] += Num[i][j] * val[j];
tot += Num[i][j] * val[j];
cnt[j] += Num[i][j];
}
}
memset(f,127,sizeof(f));
f[0][Sum[1]][Sum[2]] = 0; inf = ans = f[1][1][1];
for(int i=1;i<=6;i++) for(int j=0;j<=tot;j++) for(int k=0;k+j<=tot;k++)
if(f[i-1][j][k]!=inf) {for(int x1=0;x1<=cnt[i];x1++)
for(int x2=0;x1+x2<=cnt[i];x2++){
int now1 = j - (Num[1][i] - x1) * val[i];
int now2 = k - (Num[2][i] - x2) * val[i];
int x3 = cnt[i] - x1 - x2;
if(now1 >= 0 && now2 >= 0 && now1 + now2 <= tot){
int w = abs(Num[1][i] - x1) + abs(Num[2][i] - x2) + abs(Num[3][i] - x3);
f[i][now1][now2] = min(f[i][now1][now2] , f[i-1][j][k] + (w>>1));
}
}
}
int S1 = Sum[1] - X1 + X3 , S2 = Sum[2] - X2 + X1 , S3 = Sum[3] - X3 + X2;
for(int i=0;i<=6;i++) ans = min(ans , f[i][S1][S2]);
if(S1<0 || S2<0 || S3<0 || ans == inf) printf("impossible");
else printf("%d",ans); return 0;
}