Description
有兩個桶大小爲X和Y,開始都是空的。
有如下三種操作,最多操作K次。
①用倒滿一個桶。
②倒空一個桶。
③把一個桶裏的水倒到另一個桶裏,直到一個桶空了或者另一個桶滿了。(看哪種情況先發生)
給出要求的水量M.
最後你獲得的水量是兩個桶的水量之和M'。
求|M-M'|的最小值。
Input
一行,四個數X,Y,K,M.
1<=X,Y,K<=100
1<=M<=200
Output
輸出一個數表示最小值。
Sample Input
Sample Output
題解:
數據範圍很善良的說……於是我們想到暴力。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;
}