为了账号安全,请及时绑定邮箱和手机立即绑定

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

标签:
算法

*不了解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;}

 


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消