1.解法一:多重背包

#include<iostream>
#include<cstdio>
using namespace std;
#define MAX(a,b) (a>b)?a:b
const int SIZE=+;
int dp[SIZE];
int bag[];
int nLimit; void ZeroOnePack(int cost, int value)
{
for(int i=nLimit; i>=cost; i--)
dp[i]=MAX(dp[i],dp[i-cost]+value);
} void CompletePack(int cost, int value)
{
for(int i=cost; i<=nLimit; i++)
dp[i]=MAX(dp[i],dp[i-cost]+value);
} void MultiplyPack(int cost, int value, int amount)
{
if(amount*cost>=nLimit) CompletePack(cost,value);
else
{
int k=;
while(k<amount)
{
ZeroOnePack(k*cost, k*value);
amount-=k;
k<<=;
} ZeroOnePack(amount*cost,amount*value);
}
} bool CheckFinish()
{
for(int i=;i<=;i++)
if(bag[i]!=)
return false;
return true;
} int main()
{
int T=;
while(true)
{
int sum=;
for(int i=; i<=; i++)
{
scanf("%d",&bag[i]);
sum+=bag[i]*i;
}
if(CheckFinish())
break; printf("Collection #%d:\n",++T);
if(sum%==)
{
printf("Can't be divided.\n");
}
else
{
memset(dp,,sizeof(dp));
nLimit=sum/;
for(int i=;i<=;i++)
{
MultiplyPack(i,i,bag[i]);
}
if(dp[nLimit]==nLimit)
printf("Can be divided.\n");
else
printf("Can't be divided.\n");
}
printf("\n"); } return ;
}

2.解法二:多重部分和

#include<cstdio>
#include<cstring>
using namespace std;
const int SIZE=+;
int a[];
int dp[SIZE];
bool check()
{
for(int i=;i<;i++)
if(a[i]!=)
return true;
return false;
}
int sum; int main()
{
int t=;
while(true)
{
sum=;
for(int i=;i<;i++)
{
scanf("%d",&a[i]);
sum+=(i+)*a[i];
}
if(!check())
break; printf("Collection #%d:\n",++t);
if(sum%==)
{
printf("Can't be divided.\n");
}
else
{
memset(dp,-,sizeof(dp));
int k=sum/;
dp[]=;
for(int i=;i<;i++)
{
for(int j=;j<=k;j++)
{
if(dp[j]>=)
{
dp[j]=a[i];
}
else if(j<(i+)||dp[j-(i+)]<=)
{
dp[j]=-;
}
else
{
dp[j]=dp[j-(i+)]-;
}
}
}
if(dp[k]>=)
{
printf("Can be divided.\n");
}
else
{
printf("Can't be divided.\n");
}
}
printf("\n");
}
return ;
}

3.解法三:判断多重背包可否装满

#include<iostream>
#include<cstdio>
using namespace std;
#define MAX(a,b) (a>b)?a:b
const int SIZE=+;
const int INF=;
int dp[SIZE];
int bag[];
int nLimit;
bool CheckFinish()
{
for(int i=;i<=;i++)
if(bag[i]!=)
return false;
return true;
} int main()
{
int T=;
while(true)
{
int sum=;
for(int i=; i<=; i++)
{
scanf("%d",&bag[i]);
sum+=bag[i]*i;
}
if(CheckFinish())
break; printf("Collection #%d:\n",++T);
if(sum%==)
{
printf("Can't be divided.\n");
}
else
{
nLimit=sum/;
memset(dp,,sizeof(dp));
dp[]=;
int dpt[];
for(int i=;i<=;i++)
{
memset(dpt,,sizeof(dpt));
for(int j=i;j<=nLimit;j++)
if(!dp[j]&&dp[j-i]&&dpt[j-i]<bag[i])
{
dpt[j]=dpt[j-i]+;
dp[j]=;
}
} if(dp[nLimit])
{
printf("Can be divided.\n");
}
else
{
printf("Can't be divided.\n");
}
} printf("\n");
} return ;
}

判断模板:

memset(dp,,sizeof(dp));
dp[]=;
int used[];
for(int i=;i<=nKind;i++)
{
memset(used,,sizeof(used));
for(int j=weight[i];j<=nLimit;j++)
if(!dp[j]&&dp[j-weight[i]]&&used[j-weight[i]]<bag[i])
{
used[j]=used[j-weight[i]]+;
dp[j]=;
}
}

HDOJ1059(多重背包)的更多相关文章

  1. 洛谷P1782 旅行商的背包[多重背包]

    题目描述 小S坚信任何问题都可以在多项式时间内解决,于是他准备亲自去当一回旅行商.在出发之前,他购进了一些物品.这些物品共有n种,第i种体积为Vi,价值为Wi,共有Di件.他的背包体积是C.怎样装才能 ...

  2. HDU 2082 找单词 (多重背包)

    题意:假设有x1个字母A, x2个字母B,..... x26个字母Z,同时假设字母A的价值为1,字母B的价值为2,..... 字母Z的价值为26.那么,对于给定的字母,可以找到多少价值<=50的 ...

  3. Poj 1276 Cash Machine 多重背包

    Cash Machine Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 26172   Accepted: 9238 Des ...

  4. poj 1276 Cash Machine(多重背包)

    Cash Machine Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 33444   Accepted: 12106 De ...

  5. (混合背包 多重背包+完全背包)The Fewest Coins (poj 3260)

    http://poj.org/problem?id=3260   Description Farmer John has gone to town to buy some farm supplies. ...

  6. (多重背包+记录路径)Charlie's Change (poj 1787)

    http://poj.org/problem?id=1787   描述 Charlie is a driver of Advanced Cargo Movement, Ltd. Charlie dri ...

  7. 单调队列优化DP,多重背包

    单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...

  8. POJ1742 Coins[多重背包可行性]

    Coins Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 34814   Accepted: 11828 Descripti ...

  9. POJ1276Cash Machine[多重背包可行性]

    Cash Machine Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 32971   Accepted: 11950 De ...

随机推荐

  1. [Android]豆瓣FM离线数据

    离线目录结构: /sdcard/Android/data/com.douban.radio下 ./cache/fileCaches: 离线音乐歌词(lyric) ./cache/images: 离线音 ...

  2. python3.7.1 内置函数

    python3.7.1 内置函数列表 内置函数 abs() delattr() hash() memoryview() set() all() dict() help() min() setattr( ...

  3. MD5加密“破解”在.NET平台实现最基本的理解

    MD5作为一种散列算法,广泛用于密码传输过程中的“加密”(引号的意思是这并不是真正的加密,而是形成密码的散列值)过程.MD顾名思义Message Digest(报文摘要),可以将输入的密码,一般来说为 ...

  4. PHP新写的大转盘抽奖源码

    中奖概率 抽奖大转盘演示:http://www.sucaihuo.com/php/3301.html function getRand($proArr, $proCount) { $result = ...

  5. 20145229吴姗珊 《Java程序设计》两天小总结

    20145229吴姗珊 <Java程序设计>两天小总结 教材学习内容总结 第十章 输入\输出 1.java将输入\输出抽象化为串流,数据有来源及目的地,衔接两者的是串流对象 2.从应用程序 ...

  6. msm8909+android5.1分区及烧录的镜像文件介绍【转】

    本文转载自: EMMC的分区及其保存的文件 Partition label filename 说明 PrimaryGPT gpt_main0.bin modem NON-HLOS.bin sbl1 s ...

  7. 剑指offer之 栈的压入、弹出序列

    题目描述:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出序列.假设压入栈的所有数字均不相等.例如序列1/2/3/4/5是某栈的压栈序列,序列4/5/3/2/1是该压栈序 ...

  8. LUM使用常规命令

    查看日志 tail -f /var/log/messages LUM使用常规命令再列出一下######------ 软件操作方法:* 关闭LUM及所有组件:lu-stop* 启动LUM及所有组件:lu ...

  9. UOJ136 开学前的作文

    描述 红包是一个萌萌的男孩子. 红包由于 NOI 惨挂,直到前不久依然无心写作业.如今快开学了,他决定好好完成作业. 对于可以交电子稿的作文,红包有特殊的完成技巧,大致流程是依次选中一段内容→按下 C ...

  10. 激活idea2018

    首先下载安装完成后,打开hosts文件,新增一条路由: 0.0.0.0 account.jetbrains.com 打开软件输入序列码: EB101IWSWD-eyJsaWNlbnNlSWQiOiJF ...