我是靠谱客的博主 淡定冰淇淋,最近开发中收集的这篇文章主要介绍【动态规划】完全背包问题-疯狂的采药,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

什么是完全背包问题?

有N种物品和一个容量为V的背包,每种物品都有无限件可用。

第i种物品的体积是c,价值是w。求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大。这里不同之处是每件物品可无限取,这里就产生了很多可行的优化,比如同体积的有多种物品,则必然可以舍弃价值小的,也可以舍弃体积大于v的。

比较一下01背包问题:

在M件物品中取出若干件物品放到背包中,每件物品对应的体积v1,v2,v3,….对应的价值为w1,w2,w3,,每件物品之多拿一件。

二者的区别就是01背包里每件物品至多只能拿一件,而完全背包问题中每件物品可以无限拿。

01背包问题的解决思路是:第i件物品是否放入背包,取决于总价值的大小。
状态转移方程:f[j]=max(f[j],f[j-ti[i]]+v[i]);

for(int i=1;i<=m;i++)
for(j=t;j>=t[i];j--)//从右到左计算 
f[j]=max(f[j],f[j-ti[i]]+p[i]);

完全背包问题也是同样的思路,只是循环的方式不一样

for(int i=1;i<=m;i++)
for(int
j=ti[i];j<=t;j++)
f[j]=max(f[j],f[j-ti[i]]+v[i]);

下面的题目就是一个完全背包问题

题目描述

LiYuxiang是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同种类的草药,采每一种都需要一些时间,每一种也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”

如果你是LiYuxiang,你能完成这个任务吗?

此题和原题的不同点:

1.每种草药可以无限制地疯狂采摘。

2.药的种类眼花缭乱,采药时间好长好长啊!师傅等得菊花都谢了!

输入格式

输入第一行有两个整数T(1 <= T <= 100000)和M(1 <= M <= 10000),用一个空格隔开,T代表总共能够用来采药的时间,M代表山洞里的草药的数目。接下来的M行每行包括两个在1到10000之间(包括1和10000)的整数,分别表示采摘某种草药的时间和这种草药的价值。

输出格式

输出一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。

输入输出样例
输入 #1
70 3
71 100
69 1
1 2
输出 #1
140

代码:

#include<iostream>
#include <algorithm>
using namespace std;
int t,m;
int ti[10001],v[10001];
int f[100001];
//这是一个完全背包问题
//大概明白了,与01背包不同的是完全背包问题中每件物品的数量是无限的
//01背包每件物品只有一个 ,就放一次 
//状态转移方程到底是怎么列出来的明白了,就是这个东西放还是不放的问题
//为什么,一个顺序一个逆序结果就不同了? 需要在捉摸一下
int main(){
cin>>t>>m;
for(int i=1;i<=m;i++)
cin>>ti[i]>>v[i];
//完全背包的状态转移方程 
for(int i=1;i<=m;i++)
for(int
j=ti[i];j<=t;j++)
f[j]=max(f[j],f[j-ti[i]]+v[i]);
//01背包的状态转移方程
//for(int i=1;i<=m;i++)
//for(int j=t;j>=t[i];j--)
//
f[j]=max(f[j],f[j-ti[i]]+v[i]);	
cout<<f[t];
return 0;
}

最后

以上就是淡定冰淇淋为你收集整理的【动态规划】完全背包问题-疯狂的采药的全部内容,希望文章能够帮你解决【动态规划】完全背包问题-疯狂的采药所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(70)

评论列表共有 0 条评论

立即
投稿
返回
顶部