【BZOJ】4413: [Usaco2016 Feb]Milk Pails
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; }
叶子的离去,是风的追求,还是树的不挽留?