Description
有两个桶大小为X和Y,开始都是空的。
有如下三种操作,最多操作K次。
①用倒满一个桶。
②倒空一个桶。
③把一个桶里的水倒到另一个桶里,直到一个桶空了或者另一个桶满了。(看哪种情况先发生)
给出要求的水量M.
最后你获得的水量是两个桶的水量之和M'。
求|M-M'|的最小值。
Input
一行,四个数X,Y,K,M.
1<=X,Y,K<=100
1<=M<=200
Output
输出一个数表示最小值。
Sample Input
14 50 2 32
Sample Output
18
题解:
数据范围很善良的说……于是我们想到暴力。dp[i][j][k]表示修改i次,当前两个桶的水量分别为j和k的是否可行的状态。初始dp[0][0][0]=1(可行),于是对于每一个dp[i][][],尝试更新dp[i+1][][]是否可行。然后顺便维护一个ans就ok了。
这个貌似叫做bool dp?
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 105;
bool dp[MAXN][MAXN][MAXN];
int x, y, K, m;
int main(int argc, char *argv[])
{
int i, j, k;
cin >> x >> y >> K >> m;
int ans = 0;
dp[0][0][0] = 1;
for (i = 0; i <= K; i++)
{
for (j = 0; j <= x; j++)
for (k = 0; k <= y;k++)
if (dp[i][j][k] == 1)
{
if (abs(j + k -m)<abs(ans-m))
{
ans = j + k;
if (ans == m)
{
printf("%d\n", 0);
exit(0);
}
}
dp[i + 1][0][k] = 1;
dp[i + 1][j][0] = 1;
dp[i + 1][j][y] = 1;
dp[i + 1][x][k] = 1;
if (y - k>j) dp[i + 1][0][k + j] = 1;
else dp[i + 1][k + j - y][y] = 1;
if (k + j < x) dp[i + 1][k + j][0] = 1;
else dp[i + 1][x][k + j - x] = 1;
}
}
printf("%d\n", abs(ans - m));
return 0;
}