HDOJ 1059 POJ 1014 Dividing 【多重背包】
有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;
}