这篇题解 中转移虽然是正确的,但是所谓的“滚动数组”实现其实是有误的,甚至无法通过样例。
错误在于其状态 fi,j,k 并总从 fi−1,j,k 转移而来,而可能是从 <i−1 的位置转移来的。
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int f[1001][1001],vis[1001][1001],sum;
int main()
{
int ab, bc, ca;
cin >> ab >> bc >> ca;
int a[7], b[7], c[7], num[7];
int v[] = {0,100,50,20,10,5,1};
int Ta = 0, Tb = 0, Tc = 0;
for (int i = 1; i <= 6; ++i) cin >> a[i], Ta += a[i]*v[i];
for (int i = 1; i <= 6; ++i) cin >> b[i], Tb += b[i]*v[i];
for (int i = 1; i <= 6; ++i) cin >> c[i], Tc += c[i]*v[i];
for (int i = 1; i <= 6; ++i) num[i] = a[i] + b[i] + c[i];
sum=Ta+Tb+Tc;
Ta += ca - ab;
Tb += ab - bc;
Tc += bc - ca;
memset(f, 0x3f, sizeof (f));
f[0][0]= 0;
for (int i = 1; i <= 6; ++i) {
for (int x = Ta; x >= 0; x--)
for (int y = Tb; y >= 0; y--)
{
// to calc f[i,x,y];
for (int p = 0; p <= num[i]; ++p) if (x-p*v[i] >= 0){
for (int q = 0; p+q <= num[i]; ++q) if (y-q*v[i]>=0){
int tmp = f[x-p*v[i]][y-q*v[i]]
+ abs(p-a[i])+abs(q-b[i])+abs(p+q-a[i]-b[i]);
if (f[x][y] > tmp){
if(vis[x-p*v[i]][y-q*v[i]]!=i-1){printf("wa %d\n",i);}//这是我新增的地方
f[x][y] = tmp,vis[x][y]=i;//
}
}
}
}
}
if(f[Ta][Tb]<1000000000)
cout << f[Ta][Tb] / 2;
else
cout << "impossible";
}
在输出中 wa 出现了很多次。