HDU 1059 Dividing dp背包题解

来源:互联网 发布:数据集成的两种方法 编辑:程序博客网 时间:2024/05/22 07:47

背包问题,这一类问题应用很广了。

本题可以根据特例优化一下。

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



1 0