http://poj.org/problem?id=1014
下午A完那题并查集后,滚去睡觉,睡得跟猪一样,半小时后闹钟响了,睁眼一看天是黑的!然后我就抱怨道舍友的疯了呀,闹钟那么早,呃不对怎么这么像我的闹钟?我一看手表,卧槽,5点多,我就很郁闷什么时候脑残把早上的闹钟定到五点多了? 突然想到这是晚上。。。。。。。。哭瞎了 T T
还有呀最近LOL好火的样子,晚上在学校举办LOL决赛- -|||
当然我是不会玩这种游戏滴~
----------------------------------------------------------邪恶的分割线----------------------------------------------------------
题目大意:
给定6种价值分别为1~6的物品,输入6个数代表他们的数量,问一下能不能把他们的价值等分。
思路:
多种背包问题:有N种物品和一个容量为V的背包。第i种物品最多有n[i]件可用,每件费用是c[i],价值
是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
很显然这题的模型就是多重背包。。只不过费用和价值一样,直接套背包九讲的模版。。。。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=20000*6+10;
int n[7];
int N=6;
int dp[MAXN];
int volume;
void CompletePack(int cost,int weight)
{
for(int v=cost;v<=volume;v++)
{
dp[v]=max(dp[v],dp[v-cost]+weight);
}
}
void ZeroOnePack(int cost,int weight)
{
for(int v=volume;v>=cost;v--)
{
dp[v]=max(dp[v],dp[v-cost]+weight);
}
}
void MultiplePack(int cost,int weight,int amount)
{
if(cost * amount >= volume)
{
CompletePack(cost,weight);
return;
}
int k=1;
while(k<amount)
{
ZeroOnePack(k*cost,k*weight);
amount-=k;
k<<=1;
}
ZeroOnePack(amount *cost , amount *weight);
}
int main()
{
int kase=1;
while(1)
{
volume=0;
for(int i=1;i<=N;i++)
{
scanf("%d",&n[i]);
volume+=n[i]*i;
}
if(!volume)
break;
printf("Collection #%d:\n",kase++);
if(volume % 2 !=0)
{
printf("Can't be divided.\n\n");
continue;
}
volume>>=1;
memset(dp,0,sizeof(dp));
for(int i=1;i<=6;i++)
{
MultiplePack( i , i , n[i] );
}
bool ok=false;
for(int i=0;i<MAXN;i++)
{
if(dp[i]==volume)
{
ok=true;
}
}
if(ok)
printf("Can be divided.\n\n");
else
printf("Can't be divided.\n\n");
}
return 0;
}