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;
}
知道了解法还是先说说思路吧。题目给了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;
}
相关文章推荐
- 【POJ1014】Dividing (动态规划,多重背包)
- 经典动态规划问题 背包问题 [POJ3211][POJ2063][HDU1114][POJ1276][POJ1014][POJ1742][ZOJ3631]
- 动态规划 :POJ 1014 Dividing
- poj 1014 Dividing 【多重背包】
- POJ 1014 Dividing (多重背包问题)
- POJ 1014 Dividing ( 多重背包)
- POJ_1014 Dividing(多重背包问题)
- poj1014 Dividing(递归,多重背包)
- POJ 1837 Balance(动态规划之背包问题)
- poj 1014 & zoj 1149 Dividing(多重背包+倍增思想优化)
- poj 1014 Dividing 多重背包 二进制拆分
- POJ 1014 Dividing 多重背包
- hdu1059 &poj1014 Dividing (多重背包)
- Dividing - POJ 1014 dp背包
- 【POJ1014】Dividing 多重背包,二进制物品拆分转01背包
- 动态规划(背包问题):POJ 1742 Coins
- POJ1014 :Dividing(多重背包) 二进制优化
- POJ 1014 Dividing 多重背包
- POJ 1014 Dividing (多重可行性背包)
- POJ 1837:Balance:动态规划_背包问题变形