完全背包---动态规划

描述

直接说题意,完全背包定义有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的体积是c,价值是w。求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大。本题要求是背包恰好装满背包时,求出最大价值总和是多少。如果不能恰好装满背包,输出NO

输入
第一行: N 表示有多少组测试数据(N<7)。

接下来每组测试数据的第一行有两个整数M,V。 M表示物品种类的数目,V表示背包的总容量。(0<M<=2000,0<V<=50000)

接下来的M行每行有两个整数c,w分别表示每种物品的重量和价值(0<c<100000,0<w<100000)

输出
对应每组测试数据输出结果(如果能恰好装满背包,输出装满背包时背包内物品的最大价值总和。 如果不能恰好装满背包,输出NO)
样例输入
2
1 5
2 2
2 5
2 2
5 1
样例输出
NO
1
做这题之前必须先了解0-1背包,并知道解题思路
0-1背包的状态转移方程是
for i = 1 to N
for v = V to Ci
F [v] = max{F [v],F [v ? Ci] + Wi}完全背包就是不限制物品使用个数,可以无限使用,也就是可以重复放置一个物体
转移方程
for i = 1 to N
for v = Ci to V
F [v] = max(F [v], F [v ? Ci] + Wi)
你会发现,这个伪代码与01背包问题的伪代码只有v的循环次序不同而已。
为什么这个算法就可行呢?首先想想为什么01背包中要按照v递减的次序来
循环。让v递减是为了保证第i次循环中的状态F [i, v]是由状态F [i ? 1, v ? Ci]递
推而来。换句话说,这正是为了保证每件物品只选一次,保证在考虑“选入
第i件物品”这件策略时,依据的是一个绝无已经选入第i件物品的子结果F [i ?
1, v ? Ci]。而现在完全背包的特点恰是每种物品可选无限件,所以在考虑“加
选一件第i种物品”这种策略时,却正需要一个可能已选入第i种物品的子结
果F [i, v ? Ci],所以就可以并且必须采用v递增的顺序循环。这就是这个简单的
程序为何成立的道理。

#include <stdio.h>
#include <algorithm>
#define INF -99999999
using namespace std;
int d[50005];
int a[2005];
int w[2005];
int main(){
	int t;
	scanf("%d", &t);
	while (t--){
		int n, v;
		scanf("%d%d", &n, &v);
		d[0] = 0;
		for (int i = 1; i <= v; i++)
			d[i] = INF;
		for (int i = 0; i < n; i++){
			scanf("%d%d", &a[i], &w[i]);
		}
		for (int i = 0; i < n; i++){
			for (int j = a[i]; j <= v; j++){
				d[j] = max(d[j], d[j - a[i]] + w[i]);
			}
		}
		if (d[v] < 0)
			printf("NO\n");
		else
			printf("%d\n", d[v]);
	}
	return 0;
}

时间: 2024-10-10 21:58:35

完全背包---动态规划的相关文章

多重背包-动态规划(2)

汶川大地震——HDU 2191 简单的多重背包 时间不多 最近拖拖拉拉 暂时没时间再深入理解动态规划了 把这个改成01背包简单贴一下代码... 埋下了这样的坑 # include<iostream> # include<algorithm> # include<cstring> using namespace std; //n,m,p,h,c int dp[105]; int p[105], h[105], c[105]; int n, m; void mul_bag(

01背包 -- 动态规划的入门题目

<strong><span style="font-size:18px;">首先说什么是动态规划: 经常听到 DP: Dynamic Programming的缩写 这里的入门题是这样的: 01背包 有重量与价值分别为Wi 和 Vi的 n 个物品.请从中选出物品,在重量综合不超过w的前提下,求出价值最大的. 样例: input: n = 4 (w, v) = {(2.3), (1, 2), (3, 4), (2, 3)} W = 5 outtput: 7(选择的是

HDU246饭卡(01背包/动态规划)

动态规划的题总是 看完别人的代码自己理解着打,今天自己终于自己打一回,遇到了一点问题,不过解决后发现现在理解更透彻了. Problem Description 电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额.如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够).所以大家都希望尽量使卡上的余额最少.某天,食堂中有n种菜出售,每种菜可购买一次.已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少. Inp

hiho#1038 : 01背包 (动态规划)

#1038 : 01背包 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 且说上一周的故事里,小Hi和小Ho费劲心思终于拿到了茫茫多的奖券!而现在,终于到了小Ho领取奖励的时刻了! 小Ho现在手上有M张奖券,而奖品区有N件奖品,分别标号为1到N,其中第i件奖品需要need(i)张奖券进行兑换,同时也只能兑换一次,为了使得辛苦得到的奖券不白白浪费,小Ho给每件奖品都评了分,其中第i件奖品的评分值为value(i),表示他对这件奖品的喜好值.现在他想知道,凭借他手上的这

01背包动态规划

有n 个物品,它们有各自的重量和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和? 动态规划与分治法类似,都是把大问题拆分成小问题,通过寻找大问题与小问题的递推关系,解决一个个小问题,最终达到解决原问题的效果.但不同的是,分治法在子问题和子子问题等上被重复计算了很多次,而动态规划则具有记忆性,通过填写表把所有已经解决的子问题答案纪录下来,在新问题里需要用到的子问题可以直接提取,避免了重复计算,从而节约了时间,所以在问题满足最优性原理之后,用动态规划解决问题的核心就在于填表,表填

01背包--动态规划

https://i.cnblogs.com/EditPosts.aspx?opt=1 这里主要是想改进一下二维数组的做法,用一维数组来实现01背包,也叫做滚动数组! 先借用某位大牛的一句话:"01背包在二维数组上操作,就是为了防止一个物品被放入多次的情况" 但其实01背包也可以用一维数组来做啦! 这里是把状态只用一维数组来表示,dp[j]表示放到第j个物品(或者说是前j个物品)的时候的最大价值,少了一维,感觉好神奇...不过在我仅仅做过的题目中,好像有很多都是用滚动数组的形式... 好

0-1背包 动态规划

给定n种物品和一个背包,物品i的重量是wi,价值vi,背包的重量是C,问如何选择装入背包的物品,使装入背包中的物品总价值最大? 对于每种物品只能选择完全装入或不装入,一个物品至多装入一次. 输入:整数C>0,整数wi>0,vi>0,1≤i≤n 输出:(x1,x2,....,xn),xi∈{0,1},满足∑1≤i≤nwixi≤C最大 问题优化子结构 Pi=[{i,i+1,.......,n},Ci=C?∑1≤k≤i?1wkxk] 代表物品1-i?1已经考虑完毕,物品i-n还没有被考虑是否被

nyoj 311-完全背包 (动态规划, 完全背包)

311-完全背包 内存限制:64MB 时间限制:4000ms Special Judge: No accepted:5 submit:7 题目描述: 直接说题意,完全背包定义有N种物品和一个容量为V的背包,每种物品都有无限件可用.第i种物品的体积是c,价值是w.求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大.本题要求是背包恰好装满背包时,求出最大价值总和是多少.如果不能恰好装满背包,输出NO 输入描述: 第一行: N 表示有多少组测试数据(N<7). 接下来每组测试数

LeetCode 1049 背包动态规划

有一堆石头,每块石头的重量都是正整数. 每一回合,从中选出任意两块石头,然后将它们一起粉碎.假设石头的重量分别为 x 和 y,且 x <= y.那么粉碎的可能结果如下: 如果 x == y,那么两块石头都会被完全粉碎:如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x.最后,最多只会剩下一块石头.返回此石头最小的可能重量.如果没有石头剩下,就返回 0. 示例: 输入:[2,7,4,1,8,1]输出:1解释:组合 2 和 4,得到 2,所以数组转化为 [2