01背包与完全背包(dp复习)

01背包和完全背包都是dp入门的经典,我的dp学的十分的水,借此更新博客的机会回顾一下

01背包:给定总容量为maxv的背包,有n件物品,第i件物品的的体积为w[i],价值为v[i],问如何选取才能是背包内的物品价值总和最大。

stdin:

5

1 2 3 4 5

5 4 3 2 1

stdout:

14

设dp[i][j]为取前i件物品时容量为j的最优解。

状态转移方程:dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);

压缩后:dp[j]=max(dp[j],dp[j-w[i]]+v[i]);

for (int i = 1; i <= 4; i++) {
        for (int j = 1; j <= bagV; j++) {
            if (j < w[i])
                dp[i][j] = dp[i - 1][j];
            else
                dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
        }
    }//二维dp
for (int i = 1; i <= 4; i++) {
        for (int j = maxv; j >= w[i]; j--) {
                dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
        }
    }//一维

完全背包:在01背包的基础上,每件物品都不限次数。

从一维数组上区别0-1背包和完全背包差别就在循环顺序上,0-1背包必须逆序,因为这样保证了不会重复选择已经选择的物品,而完全背包是顺序,顺序会覆盖以前的状态,所以存在选择多次的情况,也符合完全背包的题意。状态转移方程都为dp[j] = max(dp[j],dp[j-w[i]]+v[i])。

for(int i=1; i<=n; i++)
        for(int j=w[i]; j<=V; j++)
            f[j]=max(f[j],f[j-w[i]]+c[i]);

原文地址:https://www.cnblogs.com/iloveysm/p/12249255.html

时间: 2024-08-01 13:59:23

01背包与完全背包(dp复习)的相关文章

vijos P1836HYS与七夕节大作战 (01背包之2--转换dp对象)

题目:vijos P1836HYS与七夕节大作战 题意: n个对象,每价值为vi,比重pi,总容量100 分析: 类似背包重量的比重pi为实数,不能作为下标,所以改变dp对象 将求容量100内的最大价值 → 求相应价值的最小容量, 则容量第一个≤100的价值,为符合条件的价值最大的值 状态:dp[v]:价值为v的最小容积 转移方程:         dp[V] = min(dp[V], dp[V-v[i]] + p[i]); 核心: for(i = 1; i<=n; i++) {     for

BZOJ.4753.[JSOI2016]最佳团体(01分数规划 树形背包DP)

题目链接 \(Description\) 每个点有费用si与价值pi,要求选一些带根的连通块,总大小为k,使得 \(\frac{∑pi}{∑si}\) 最大 \(Solution\) 01分数规划,然后dp,设f[i][j]表示i子树选j个的最大权值和,直接暴力背包转移即可 在枚举子节点选的数量时,假设x有1.2.3.4四个子节点,复杂度为 \(1*sz[1]+sz[1]*sz[2]+(sz[1]+sz[2])*sz[3]+(sz[1]+sz[2]+sz[3])*sz[4]\) 相当于每对点在L

01背包 两维背包

#include <iostream> #include <algorithm> using namespace std; /******************************** 01背包 */ #define N 5 #define M 12 int value[N + 1] = { 0, 6, 3, 5, 4, 6 }; int weight[N + 1] = { 0, 2, 2, 6, 5, 4 }; //#define N 5 //#define M 8 //i

有关货币问题的动态规划题目--有关01背包,完全背包,多重背包

背包dp:参考背包九讲以及给出一些题目 01背包 (先枚举物品,再逆序枚举容量) 给定n件物品和一个容量为V的背包,每件物品的体积是w[i],价值是va[i](1<=i<=n),求在不超过背包的容量的情况下,怎么选择装这些物品使得得到的价值最大? 例如:有5件物品,体积分别是{2,2,6,5,4},价值分别是{6,3,5,4,6} 递归式:F(i,v)=max(F(i-1,v), F(i-1,v-w[i])+va[i]),其中F(i,v)表示把前i种物品恰放入背包容量为v时取得的最大价值 把这

[动态规划] 01背包与完全背包

01背包(每种物品的状态为选择或不选择,最多只能选1件): 1.传统的二维数组,第i件物品的重量为w[i],价值为v[i] dp[i][j]保存的是选择前i件物品(每一件物品的状态为选与不选),在背包容量为j的情况下,可以获得的最大价值 两种情况: 一.当前背包容量j<第i件的重量时,第i件背包肯定不能选,放不下去,有dp[i][j]=dp[i-1][j] 二.当前背包容量j>=第i件的重量时,第i件背包可以选,能放得下去,但因为要考虑到所获得最大价值,所以这时候有两种选择,选或不选,我们要在

HDU 3033 I love sneakers! (01背包+反分组背包)

题意:给你 n,m,k,表示有k种鞋子共n双,你有m的容量: 每双鞋子有容量p和价值v:问是否买全k种鞋子,若能在容量为m的情况下最多能买到鞋子的价值为多少: 每双鞋子只能买一次(01背包),每种鞋子至少买一种(分组背包:每组只能有一个)与传统分组背包的限制相反. 注意初始化!!! #include<cstdio> #include<stdlib.h> #include<string.h> #include<string> #include<map&g

HDU 5410 CRB and His Birthday (01背包,完全背包,混合)

题意:有n种商品,每种商品中有a个糖果,如果买这种商品就送多b个糖果,只有第一次买的时候才送.现在有m元,最多能买多少糖果? 思路:第一次买一种商品时有送糖果,对这一次进行一次01背包,也就是只能买一次.然后对这种商品来一次完全背包,此时不送糖果,也可以多买. 1 #include <bits/stdc++.h> 2 #define pii pair<int,int> 3 #define INF 0x7f7f7f7f 4 #define LL long long 5 using n

【算法学习笔记】30.动态规划 01背包和完全背包的关系

首先先说明一下01背包和完全背包问题的区别 01背包:有 N 件物品和一个容量为 V 的背包.放入第 i 件物品耗费的费用是 Ci,得到的价值是 Wi.求解将哪些物品装入背包可使价值总和最大.(可以不装满) 完全背包:有 N 种物品和一个容量为 V 的背包,每种物品都有无限件可用.放入第 i 种物品 的费用是 Ci,价值是 Wi.求解:将哪些物品装入背包,可使这些物品的耗费的费用总和不超过背包容量,且价值总和最大. 先说结论: 两个问题的最优解都要用DP来解决,实现的过程也非常像只是在内层循环中

背包之01背包、完全背包、多重背包详解

首先说下动态规划,动态规划这东西就和递归一样,只能找局部关系,若想全部列出来,是很难的,比如汉诺塔.你可以说先把除最后一层的其他所有层都移动到2,再把最后一层移动到3,最后再把其余的从2移动到3,这是一个直观的关系,但是想列举出来是很难的,也许当层数n=3时还可以模拟下,再大一些就不可能了,所以,诸如递归,动态规划之类的,不能细想,只能找局部关系. 1.汉诺塔图片 (引至杭电课件:DP最关键的就是状态,在DP时用到的数组时,也就是存储的每个状态的最优值,也就是记忆化搜索) 要了解背包,首先得清楚