题目来源:http://poj.org/problem?id=1014
题目大意:
Marsha和Bill拥有一些弹珠。但是这些弹珠的价值不一样。每个弹珠的价值都是1到6之间的自然数。他们希望把这些弹珠分为两份,每份的总价值相等。然而,有时候是不存在这样的划分的(即使总的价值为偶数)。比如弹珠的价值分别为1,3,4,4.写一个程序判断一些弹珠是否可以被分为价值相等的两份。
输入:每行代表一个测试用例,含6个非负整数。n1,...n6.ni表示价值为i的弹珠有多少个。测试用例最多20000个。输入以“0 0 0 0 0 0”结束。
输出:对于每个用例,若可分,输出: "Collection #k:", 其中k为用例编号, "Can be divided." 或 "Can't be divided."每个用例输出之后接一个空白行。
Sample Input
1 0 1 2 0 0 1 0 0 0 1 1 0 0 0 0 0 0
Sample Output
Collection #1: Can't be divided. Collection #2: Can be divided.
首先,如果弹珠的总价值为奇数一定不可分,然后,用dfs搜索,找出所有弹珠中的一个子集,使其和为总价值的一半,若能找到则可分,反之不可分。
1 ////////////////////////////////////////////////////////////////////////// 2 // POJ1014 Dividing 3 // Memory: 596K Time: 0MS 4 // Language: C++ Result: Accepted 5 ////////////////////////////////////////////////////////////////////////// 6 7 #include <iostream> 8 9 using namespace std; 10 11 int stone[6]; 12 int totalValue; 13 bool flag = false; 14 15 bool dfs(int sum, int s, int target) { 16 if (flag) return true; 17 if (sum == target) { 18 return true; 19 } 20 for (int i = s; i >0; --i) { 21 if (stone[i - 1]) { 22 if (sum + i <= target) { 23 --stone[i - 1]; 24 if (dfs(sum + i, i, target)) return true; 25 } 26 } 27 } 28 return false; 29 } 30 31 int main(void) { 32 33 int caseNo = 0; 34 while (true) { 35 totalValue = 0; 36 flag = false; 37 for (int i = 0; i < 6; i++) { 38 cin >> stone[i]; 39 totalValue += stone[i] * (i + 1); 40 } 41 if ((stone[0] || stone[1] || stone[2] || stone[3] || stone[4] || stone[5]) == 0) { 42 break; 43 } 44 ++caseNo; 45 //若价值和为奇数,一定不可分 46 if (totalValue % 2 == 1) { 47 cout<<"Collection #"<<caseNo<<':'<<endl; 48 cout<<"Can't be divided."<<endl<<endl; 49 continue; 50 } 51 if (dfs(0, 6, totalValue / 2)) { 52 cout<<"Collection #"<<caseNo<<':'<<endl; 53 cout<<"Can be divided."<<endl<<endl; 54 continue; 55 } 56 else { 57 cout<<"Collection #"<<caseNo<<':'<<endl; 58 cout<<"Can't be divided."<<endl<<endl; 59 continue; 60 } 61 } 62 system("pause"); 63 return 0; 64 }