就是判断弹珠是否可以平分,一开始想到了背包模型。一开始转画成了01背包。wa了。那是就一直在纠结物品的cost是什么,假设成了1,后来一直不对,看了题解他们将cost 设定等于就是将cost等同于weight.就是在寻找也可以转化这样想,将所给的标准就是cost,也就是体积的话,问题就转化成了在不考虑价值的情况下。怎么分配可以放满容积为 sum / 2 的背包。
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int MAXN = 2e5 + 10;
int c[MAXN];
int w[MAXN];
int dp[MAXN * 6];
bool tag;
int v;
void CompeletePack(int w,int c)
{
for(int i = c;i <= v;++i)
{
dp[i] = max(dp[i],dp[i - c] + w);
if(dp[i] == v)
{
tag = 1;
return ;
}
}
return ;
}
void ZeroOnePack(int w,int c)
{
for(int i = v;i >= c;--i)
{
dp[i] = max(dp[i],dp[i - c] + w);
if(dp[i] == v)
{
tag = 1;
return ;
}
}
return ;
}
void MultiplePack(int w,int c,int a)
{
if(c * a >= v)
{
CompeletePack(w,c);
return ;
}
int k = 1;
while(k < a)
{
ZeroOnePack(k * w,k * c);
if(tag)
return ;
k *= 2;
a -= k;
}
ZeroOnePack(w * a,c * a);
}
int main()
{
int a[10];
int t = 1;
while(1)
{
int sum = 0,s = 0;
for(int i = 1;i <= 6;++i)
{
cin >> a[i];
sum += a[i] * i;
s += a[i];
}
v = sum / 2;
if(!s)
break;
else
{
cout << "Collection #" << t++ << ':' << endl;
if(sum % 2)
cout << "Can't be divided." << endl << endl;
else
{
memset(dp,-1,sizeof(dp));
dp[0] = 0;
tag = 0;
for(int i = 1;i <= 6;++i)
{
MultiplePack(i,i,a[i]);
if(tag) break;
}
if(tag)
cout << "Can be divided." << endl << endl;
else
cout << "Can't be divided." << endl << endl;
} }
}
}