P4026题解
题目
传送门
分析
一道极其诡异的题目
我们千万不要被题目所迷惑,去考虑要循环地还钱。要重新理解一下怎样还钱。
第一步:ABC 三人把所有的钱掏出来,放在桌子上
第二步:AB 拿走他们应该拿走的钱,剩下的就是 C 该拿走的钱
所谓的交换代价,就是指原本的钱减去拿走的钱的绝对值。怎么理解?
假设 A 原本有
其中
设 A 应该拿走
同理:
问题就转化为了:求六种货币,能够取两个集合,
好了,来玩背包吧
背包
设
令
最后答案就是
有人说这个会
代码
方程都列的这么详细了,代码还需要吗?
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int f[1001][1001];
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];
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)
f[x][y] = tmp;
}
}
}
}
if(f[Ta][Tb]<1000000000)
cout << f[Ta][Tb] / 2;
else
cout << "impossible";
}
望通过,谢谢