继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

背包——完全背包Warcraft III(哈理工1053)

九日王朝
关注TA
已关注
手记 180
粉丝 41
获赞 185

*不了解01背包的同学请移步  http://blog.csdn.net/sm9sun/article/details/53235986


题目链接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1053

题目描述:

是一道最原始最基本的完全背包题,题意就是魔兽有不同的兵种
他们的攻击力与建造他们的金币都不相同,每个兵种可以无限出。 
开始输入一个t,表示测试t组数据,然后一个g和n,g表示你拥有的金币 
n表示有n个兵种。接下来输入n行数据,每行两个数a[i],b[i]
a[i]表示不同兵种的攻击力,b[i]表示所需的金币 
最后输出总共能获得的最大攻击力 


首先来说明一下完全背包,与多重、01背包不同,完全背包的物品是无限的。那么我们是否可以用多重背包的思路去解决完全背包呢?

我每个物品的取值肯定是有限的,就是总容量/个体容量。那么我就当作是这么多个呗,这个想法可行吗?答案是可行的。

不过我们也不用这么麻烦,每个物品可以取无限次对于我们来说未尝不是好事,因为我们也不用管物品[i]的层次了,他取完我也可以再去

即 我们不用采取dp[i-1][j]构造dp[i][j]的方式,直接遍历所有的重量点即可,加入一个物品n后,每个重量点都看看dp[j-b[i]]+a[i]是否大于原dp[j]

for(i=1;i<=n;i++)     //外层循环依旧是个数 
for(j=b[i];j<=g;j++)   //内层循环依旧是重量,这里是价值 
dp[j]=fmax(dp[j],dp[j-b[i]]+a[i]); 

我们会发现 其实状态转移方程还是和01背包一样~



#include<stdio.h>int fmax(int a,int b)         //最大值函数 {	return a>b?a:b;}int main(){	int i,j,n,g,t;     //控制循环,n兵种数,g钱数,t测试数据 	int a[10000],b[10000];         //a数组攻击力  b数组所需金币 	int dp[10000];          //构造动态规划数组 	scanf("%d",&t);	while(t--)	{		scanf("%d%d",&g,&n);		for(i=1;i<=n;i++)		scanf("%d%d",&a[i],&b[i]);for(i=0;i<=g;i++)    //价值初始化 dp[i]=0;for(i=1;i<=n;i++)     //外层循环依旧是个数 		for(j=b[i];j<=g;j++)   //内层循环依旧是重量,这里是价值 		dp[j]=fmax(dp[j],dp[j-b[i]]+a[i]);								/*为什么循环从b[i]开始呢?小于单价的重量点不会受影响*/printf("%d\n",dp[g]);}return 0;}

 


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP