藍橋杯---Sharing Chocolate---狀壓+記憶化

試題 算法提高 Sharing Chocolate

資源限制

  時間限制:1.0s 內存限制:128.0MB

問題描述

  每天,巧克力在它的許多形式上被全世界數百萬人分享。它是一個真正普遍的糖果,實際上在世界上每個國家都能得到。
  你發現唯一比吃巧克力更好的事情是把它分享給朋友。不幸的是,你的朋友非常挑剔,有着不同的胃口:有的喜歡讓你提供較多的巧克力,而其他的喜歡讓你提供較少的巧克力。你發現當他們的要求可以相互疊加時,這個事情就變得越來越難決斷。現在是寫一個程序來一次性完全解決這個問題的時間!
  你的巧克力是矩形的。巧克力由同樣大小的矩形塊組成。你可以沿着巧克力中行或者列的分割線將巧克力分成兩塊來分享你的巧克力。你可以重複地用同樣手段將分成的小塊繼續分割。你的每個朋友堅持要得到巧克力中的一個矩形部分,這個部分包含一個確定地小塊數。你也有些堅持心:如果這塊巧克力能全部分給你的朋友,不剩下任何部分,你纔會分割你的巧克力。
  例如圖9表示將一個由3×4個小塊組成巧克力塊分割3次,分成各自包含6、3、2、1個小塊的4部分的一種方法。(這相當於輸入樣例中第一個測試數據。)

輸入格式

  輸入數據包含多組測試數據,每組測試數據描述一個要分享的巧克力塊。每組測試數據的第一行包含一個整數n(1<=n<=15),表示巧克力需要分割成的塊數。第二行包含兩個整數x、y,表示巧克力塊的兩個方向上的長度。第三行包含n個正整數,表示n個部分各自需要包含的小塊數。
  輸入數據終止於只包含整數0的一行。

輸出格式

  對於每組測試數據,先輸出它的測試點編號。然後輸出將巧克力按照指定的方法分割是否有可能:如果可能,輸出“Yes”,否則輸出“No”。按照輸出樣例中的格式輸出。

樣例輸入

4
3 4
6 3 2 1
2
2 3
1 5
0

樣例輸出

Case 1: Yes
Case 2: No

數據規模和約定

  對於40%的數據,1<=n<=5,1<=x,y<=10;
  對於全部的數據,1<=n<=15,1<=x,y<=100,輸入文件保證測試點個數不超過10。

實現代碼

#include<iostream>
#include<cstring>
#define min(a, b) ((a) < (b) ? (a) : (b))

using namespace std;

int sum[1 << 15], dp[1 << 15][105], maxn, ans;

int bitcount(int x) { return !x ? 0 : bitcount(x >> 1) + (x & 1); } //計算有幾個狀態符合

int cal(int s, int x) {
	if (dp[s][x] != -1) return dp[s][x];
	if (bitcount(s) == 1) return dp[s][x] = 1;
	int y = sum[s] / x;
	for (int a = (s - 1) & s; a; a = (a - 1)& s) { //分到只剩下一塊就不能分,本身沒有的塊也不能分出來
		int b = (s ^ a);
		if (sum[a] % x == 0 && cal(a, min(x, sum[a] / x)) && cal(b, min(x, sum[b] / x))) return dp[s][x] = 1;
		if (sum[a] % y == 0 && cal(a, min(y, sum[a] / y)) && cal(b, min(y, sum[b] / y))) return dp[s][x] = 1;
	}
	return dp[s][x] = 0;
}

int main() { 
	int n, r, c, tmp, cnt = 0;
	while (cin >> n && n) {
		memset(dp, -1, sizeof(dp));
		memset(sum, 0, sizeof(sum));
		maxn = (1 << n) - 1;
		cin >> r >> c;
		for (int i = 0; i < n; i++) {
			cin >> tmp;
			for (int j = 0; j <= maxn; j++) if (j & (1 << i)) sum[j] += tmp;
		}
		ans = r * c != sum[maxn] ? 0 : cal(maxn, min(r, c));
		cout << "Case " << ++cnt << ": " << (ans ? "Yes" : "No") << endl;
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章