您的位置:首页 > 其它

动态规划 :POJ 1014 Dividing

2010-07-09 04:08 309 查看
#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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: