题目地址:http://acm.nyist.net/JudgeOnline/problem.php?pid=546
思路:和杭电1171几乎一模一样,多重背包,题目说的是总价值不超过一万结果是不超过十万,老是RE,想死的心都有了,深搜也可以,懒得写了
AC代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>
#include <cctype>
const int inf = 0x7f7f7f7f;//2139062143
typedef long long ll;
using namespace std;
int dp[100010];
int a[15];
int sum;
void zeroone_pack(int value)
{
for(int i=sum; i>=value; i--)
{
dp[i] = max(dp[i],dp[i-value] + value);
}
}
void complete_pack(int value)
{
for(int i=value; i<=sum; i++)
{
dp[i] = max(dp[i],dp[i-value] + value);
}
}
void multi_pack()
{
int i,count,k;
for(i=1; i<=10; i++)
{
if(a[i] == 0)
{
continue;
}
if(a[i] * i >= sum)
{
complete_pack(i);
}
else//转化为01背包
{
k = 1;
count = a[i];
while(k < count)
{
zeroone_pack(k*i);
count -= k;
k *= 2;
}
zeroone_pack(count*i);
}
}
}
int main()
{
int i;
int k = 1;
while(true)
{
memset(dp,0,sizeof(dp));
sum = 0;
for(i=1; i<=10; i++)
{
scanf("%d",&a[i]);
sum += i * a[i];
}
if(sum == 0)
{
break;
}
if(sum & 1)//位运算比取余运算快
{
printf("#%d:Can't be divided.\n\n",k++);
continue;
}
sum /= 2;
multi_pack();
if(dp[sum] == sum)
{
printf("#%d:Can be divided.\n\n",k++);
}
else
{
printf("#%d:Can't be divided.\n\n",k++);
}
}
return 0;
}