动态规划 :POJ 1014 Dividing

#include <stdio.h> #include <string.h> int array[7] = {0}; char flag[60001] = {0}; int main() { int sum = 0, n = 0; while (1) { n++; scanf("%d %d %d %d %d %d", &array[1], &array[2], &array[3], &array[4], &array[5], &array[6]); sum = 1*array[1] + 2*array[2] + 3*array[3] + 4*array[4] + 5*array[5] + 6*array[6]; if (sum == 0) { break; } if (sum % 2 == 1) { printf("Collection #%d:/nCan't be divided./n/n", n); continue; } flag[0] = 1; int i, j, k; for (i=1; i<=6; ++i) { if (array[i] == 0) { continue; } for (j=sum/2; j>=0; --j) { if (flag[j] == 1) { for (k=1; k<=array[i]; ++k) { if (j+k*i > sum/2 || flag[j+k*i] == 1) { break; } flag[j+k*i] = 1; if (flag[sum/2] == 1) { break; } } } } } if (flag[sum/2] == 1) { printf("Collection #%d:/nCan be divided./n/n", n); } else { printf("Collection #%d:/nCan't be divided./n/n", n); } memset(flag, 0, 60001); } return 0; }

思路:是否能均分,可以转化为是否能够拿出value为sum/2的石子。flag[i]如果为1,则表示能够拿出value为i的石子。所以问题的最终解即为:flag[sum/2]是否为1。
如果存在value为K的石子,且能够拿出value为i的石子,即flag[i] = 1,则肯定也能拿出value为i+K的石子,即flag[i+K]肯定也为1。所以,我们的初始状态是flag[0] = 1,要从它推导出flag[sum/2]是否为1。

你可能感兴趣的:(include)