您的位置:首页 > 其它

HDOJ 1059 POJ 1014 Dividing 【多重背包】

2016-10-26 14:51 441 查看
有ai个重量为i的物品,i=1,2,3,4,5,6

问是否存在某种分配方案,把他们平均分?

其实这个题可以直接用多重背包搞:但是!对于每个题要仔细分析特点

举个例子,10000 10000 10000 10000 10000 10000这组数据

这么大的值有意义吗?其实并没有对吧。因为太大的值,我们可以提前平均分好

其实10000是等价于可以平均分的

但是,是偶数不能直接变成0。为什么?

再举个例子:1 2 1 0 0 0

看到这组数据其实是可以平均分的,因为1+3==2+2

但是,如果把2删掉,剩下的1和3是不能平均分的,会导致wa

所以呢,我们把很大的值变小,而且不改变奇偶性:改成5和6即可

那么这么小的数据,直接01背包,多背几次就好

代码如下:

//#include<bits/stdc++.h>
//using namespace std;
#include<iostream>
#include<cstdio>
#include<stdio.h>
#include<cstdlib>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<cstring>
using namespace std;

const int maxn=1000;
int a[10],sum;
int dp[maxn];

int main(){
int Case=0;
while(1){
sum=0;
if (Case) puts("");
Case++;
for(int i=1;i<=6;i++){
scanf("%d",&a[i]);
if (a[i]%2)
a[i]=min(a[i],5);
else
a[i]=min(a[i],6);
sum=sum+a[i]*i;
}
if (sum==0) break;
if (sum%2){
printf("Collection #%d:\nCan't be divided.\n",Case);
continue;
}
memset(dp,0,sizeof(dp));
dp[0]=1;
for(int i=1;i<=6;i++)
for(int j=1;j<=a[i];j++)
for(int k=sum;k>=i;k--)
if (dp[k-i])
dp[k]=1;
if (dp[sum/2])
printf("Collection #%d:\nCan be divided.\n",Case);
else
printf("Collection #%d:\nCan't be divided.\n",Case);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: