/* 这题很水,但是不好想。 直接开4维数组会超内存,用一个三维数组+变量传递来代替四维数组。 d[i][j][k]代表用i个面值为1的硬币j个面值为5的硬币和k个面值为10的硬币买coke个可乐 所用的最少硬币,状态转移方程有好几个就不写了,详情见代码。 还有提醒一下 输入 2 8 0 1 结果是 8 因为10+3*1=coke*1+5;(coke代表一瓶可乐) 如果你的程序没有考虑这个情况的话结果是9 就不是最优解。 */ #include <stdio.h> #include <string.h> int co,n1,n5,n0,d[705][155][155]; int min(int a,int b) { if(a<b) return a; else return b; } int dp(int a,int b,int c,int coke) { if(coke==0) return 0; int &res=d[a][b][c]; if(res<(1<<28)) return res; if(a>=8) res=min(res,dp(a-8,b,c,coke-1)+8); if(a>=3&&b>=1) res=min(res,dp(a-3,b-1,c,coke-1)+4); if(b>=2) res=min(res,dp(a+2,b-2,c,coke-1)+2); if(c>=1) res=min(res,dp(a+2,b,c-1,coke-1)+1); if(c>=1&&a>=3) res=min(res,dp(a-3,b+1,c-1,coke-1)+4); return d[a][b][c]; } int main() { int t; scanf("%d",&t); while(t--) { ci=0; scanf("%d%d%d%d",&co,&n1,&n5,&n0); memset(d,0x7f,sizeof(d)); dp(n1,n5,n0,co); printf("%d\n",d[n1][n5][n0]); } return 0; }