您的位置:首页 > 其它

POJ 1014 Dividing (动态规划、多重背包)

2011-07-10 18:55 465 查看
这是一道典型的多重背包问题。刚开始写的时候就是用最简单的多重背包的解法,也就是将多重背包转化成01背包来求解,结果T了很多次。后来转化成完全背包和01背包来求解,不过没有用log的算法进行优化,还是t。最后只好使用log的优化来优化转化为01背包的问题。
知道了解法还是先说说思路吧。题目给了6种物品,每种物品的件数,然后问能否平分。我们把所有的物品看成价值和费用相同的物品,然后使用多重背包的算法就行求解,看一半的总的价值的背包容量能否正好装一半的价值。如果可以就是可以平分否则就是不能平分。
下面是ac代码供参考:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX 70010
int dp[2*MAX];
int a[10];
int inline max(int a,int b)
{
if(a>b) return a;
else return b;
}

int solve(int n,int v)
{
int i,j,k,amount;
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
{
if(a[i]*i>=v)//完全背包
{
for(j=i;j<=v;j++)
dp[j]=max(dp[j],dp[j-i]+i);
}
else//01背包
{
k=1;
amount=a[i];
while(k<amount)
{
for(j=v;j>=k*i;j--)
dp[j]=max(dp[j],dp[j-k*i]+k*i);
amount-=k;
k*=2;
}
for(j=v;j>=amount*i;j--)
dp[j]=max(dp[j],dp[j-amount*i]+amount*i);
}
}
return dp[v];
}

int main()
{
int cas=0,flag,i,sum;
while(1)
{
cas++;
sum=0;
for(i=1;i<=6;i++)
{
scanf("%d",&a[i]);
sum+=a[i]*i;
}
flag=0;
for(i=1;i<7;i++)
{
if(a[i]!=0)
{
flag=1;
break;
}
}
if(flag==0)
{
break;
}
if(sum%2==1)
{
printf("Collection #%d:\nCan't be divided.\n\n",cas);
continue;
}
i=solve(6,sum/2);
if(i==(sum/2))
printf("Collection #%d:\nCan be divided.\n\n",cas);
else
printf("Collection #%d:\nCan't be divided.\n\n",cas);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  优化 算法