【BZOJ】4413: [Usaco2016 Feb]Milk Pails bool型dp

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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章