背包问题,这一类问题应用很广了。
本题可以根据特例优化一下。
#include <stdio.h> #include <vector> #include <string.h> #include <algorithm> #include <iostream> #include <string> #include <limits.h> #include <stack> #include <queue> #include <set> #include <map> using namespace std; const int MAX_N = 20001; const int ARR_SIZE = 6; int N, arr[ARR_SIZE], tbl[MAX_N * ARR_SIZE]; bool dividable(int sum) { if (sum & 1) return false; int half = sum >> 1; memset(tbl, 0, sizeof(int) * (half+1)); tbl[0] = 1; for (int i = 0; i < ARR_SIZE; i++) { if (arr[i] == 0) continue; int v = i+1; for (int j = 0; j <= half; j++) { if (tbl[j]) tbl[j] = arr[i]+1; else if (j >= v && tbl[j-v] > 1) { tbl[j] = tbl[j-v] - 1; } } } return tbl[half] > 0; } int main() { int minNum, sum, t = 1; while (true) { minNum = INT_MAX; sum = 0; for (int i = 0; i < ARR_SIZE; i++) { scanf("%d", arr+i); minNum = min(minNum, arr[i]); sum += arr[i] * (i+1); } if (0 == sum) break;//结束条件 if (t > 1) putchar('\n'); printf("Collection #%d:\n", t++); if (sum & 1)//剪枝 { puts("Can't be divided."); continue; } if (minNum)//优化 { for (int i = 0; i < ARR_SIZE; i++) { arr[i] -= minNum; sum -= (i+1) * minNum; } if (minNum & 1) { arr[2] += 1, arr[3] += 1; sum += 3 + 4; } } if (dividable(sum)) puts("Can be divided."); else puts("Can't be divided."); } return 0; }
时间: 2024-10-13 20:09:58