多重背包,可转化为01背包,但是不能直接用最原始的物品拆分,因为总数太多了,一看这题TLE的数量就知道这么搞不行。。用二进制方式对基础物品进行组合,这样总物品数就大大减少了,具体可见背包九讲
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
int main()
{
int a[6], count = 0;
vector<int> V;
bool dp[100001];
while (true)
{
bool flag = false;
for (int i = 0; i < 6; i++)
{
scanf("%d", &a[i]);
if (a[i])
flag = true;
}
if (!flag)
break;
printf("Collection #%d:\n", ++count);
V.clear();
int total = 0;
for (int i = 0; i < 6; i++)
if (a[i])
{
total += a[i] * (i + 1);
int now = 1, sum = 0;
while (sum + now < a[i])
{
V.push_back(now * (i + 1));
sum += now;
now *= 2;
}
V.push_back((a[i] - sum) * (i + 1));
}
if (total % 2)
{
puts("Can't be divided.\n");
continue;
}
memset(dp, 0, sizeof(dp));
dp[0] = true;
int max = total / 2;
bool can = false;
for (size_t i = 0; i < V.size() && !can; i++)
for (int j = max; j >= V[i]; j--)
{
if (dp[j - V[i]])
dp[j] = true;
if (j == max && dp[j])
{
puts("Can be divided.\n");
can = true;
break;
}
}
if (!can)
puts("Can't be divided.\n");
}
return 0;
}