1.背包dp

1.0-1 背包                  2.完全背包                3.多重背包                4.二进制分组优化

5.单调队列优化          6.混合背包                7.二维费用背包        8.分组背包

9.有依赖的背包         10.泛化物品的背包        11.杂项小优化        12.背包问题变种

13.输出方案求方案数        14.求最优方案总

1.01-背包(滚动数组优化后的)

// C++ Version
for (int i = 1; i <= n; i++)for (int l = W; l >= w[i]; l--) f[l] = max(f[l], f[l - w[i]] + v[i]);

2.完全背包(已优化)

// C++ Version
for (int i = 1; i <= n; i++)for (int l = 0; l <= W - w[i]; l++)f[l + w[i]] = max(f[l] + v[i], f[l + w[i]]);
// 由 f[i][l + w[i]] = max(max(f[i - 1][l + w[i]],f[i - 1][l] + w[i]),f[i][l +
// w[i]]); 简化而来

 求dp数组中大于大于0的数量

ans = count_if(dp+1,dp+1+m,bind2nd(greater_equal<int>(),0));

3.多重背包

多重背包oj题

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int a[110], c[110],n,m;
int dp[100010];int main(){while(scanf("%d %d",&n,&m)&&n){memset(dp,-1,sizeof(dp));for(int i = 0; i < n; i ++)scanf("%d",&a[i]);for(int i = 0; i < n; i ++)scanf("%d",&c[i]);dp[0]=0;for(int i = 0; i < n; i ++){for(int j = 0; j <= m; j ++){if(dp[j] >= 0)dp[j] = c[i];else if(j < a[i] || dp[j-a[i]] <=0)dp[j] = -1;else dp[j] = dp[j-a[i]]-1;}}int ans = count_if(dp+1,dp+1+m,bind2nd(greater_equal<int>(),0));printf("%d\n",ans);}return 0;
}

4.二进制分组优化 

// C++ Version
index = 0;
for (int i = 1; i <= m; i++) {int c = 1, p, h, k;cin >> p >> h >> k;while (k - c > 0) {k -= c;list[++index].w = c * p;list[index].v = c * h;c *= 2;}list[++index].w = p * k;list[index].v = h * k;
}

 同上一题代码!!!!优化的

#include<iostream>
#include<cstdio>
#include<cstring>using namespace std;#define Maxn 100010
#define INF 0x3f3f3f3fint dp[Maxn],v[105],num[105],tmp_v[Maxn],book[Maxn];int main(void)
{// freopen("in.txt","r",stdin);// freopen("out.txt","w",stdout);int kind,max_p;while (scanf("%d%d",&kind,&max_p) != EOF) {if(!kind && !max_p) break;for (int i = 1; i <= kind; ++i) scanf("%d",&v[i]);for (int i = 1; i <= kind; ++i) scanf("%d",&num[i]);memset(dp,0,sizeof(dp));int cnt = 1;  // 用单独的数组存取拆分后的所有面值for (int i = 1; i <= kind; ++i) {for (int j = 1; j <= num[i]; j <<= 1) {tmp_v[cnt] = j*v[i];num[i]-=j;cnt++;}if(num[i] > 0) tmp_v[cnt++] = num[i]*v[i];}//用上面拆分后的数组做01背包的处理// 这里并没有用01背包去求最大值,而是把能够满足条件的状态dp 赋值为1,下标就是能够组合得到的总面值,//否则为 0 ,不存在这样的面值memset(book,0,sizeof(book));int max_ = 1;  int ans = 0;for (int i = 1; i < cnt; ++i) {max_+=tmp_v[i];max_ = min(max_p,max_);for (int j = max_; j >= tmp_v[i]; --j) {   //j的循环做了一些剪枝,因为遍历是从右往左的,在纸上模拟一下if(dp[j]) continue;                     //就会明白,当前j遍历的最大值就是把以前用过的面值的累加,最小值就是if(j == tmp_v[i]) dp[j] = 1;            //当前物体的面值;else if(j-tmp_v[i] > 0 && dp[j-tmp_v[i]]) dp[j] = 1;if(!book[j] && dp[j]) { ans++; book[j] = 1; }}}printf("%d\n",ans);}return 0;
}

5.分组背包

有 N 组物品和一个容量是 V的背包。

每组物品有若干个,同一组内的物品最多只能选一个。
每件物品的体积是 vij,价值是 wij,其中 i是组号,j是组内编号。

求解将哪些物品装入背包,可使物品总体积不超过背包容量,且总价值最大。

输出最大价值。

它和01背包很像,只不过是分开成为组合!

动态规划题目:

1.01背包:

01背包模板

#include<bits/stdc++.h>
using  namespace std;
#define int long long
typedef long long ll;
#define endl '\n'
#define int long long
const int N = 2e5 + 5;int dp[N];
int v[N], w[N];void Solve() {int n, m; cin >> n >> m;for (int i = 1; i <= n; ++i)cin >> v[i] >> w[i];for (int i = 1; i <= n; ++i){for (int j = m; j >= v[i]; --j)dp[j] = max(dp[j], dp[j - v[i]] + w[i]);}cout << dp[m] << endl;}signed main()
{std::ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);int t;Solve();
}

2.完全背包

完全背包模板

void Solve() {int n, m; cin >> n >> m;for (int i = 1; i <= n; ++i)cin >> v[i] >> w[i];for (int i = 1; i <= n; ++i){for (int j = v[i]; j <=m; ++j){dp[j] = max(dp[j], dp[j - v[i]] + w[i]);}}cout << dp[m] << endl;}

3.多重背包

朴素多重背包模板acwing

int dp[N];
int v[N], w[N];void Solve() {int n, m; cin >> n >> m;for (int i = 1; i <= n; ++i){int v, w, s;cin >> v >> w >> s;for (int j = m; j >= 0; --j){for (int k = 0; k <= s && k * v <= j; ++k){dp[j] = max(dp[j], dp[j - v * k] + w * k);}}}cout << dp[m] << endl;
}

4.多重背包二进制优化:

多重背包ACwing

#include<bits/stdc++.h>
using  namespace std;
#define int long long
typedef long long ll;
#define endl '\n'
#define int long long
const int N = 2e5 + 5;int dp[N];
int v[N], w[N];
int cnt[N];void Solve() {int cnt = 0;int n, m; cin >> n >> m;cnt = 0;for (int i = 1; i <= n; ++i){int vv, ww, ss; cin >> vv >> ww >> ss;int k = 1;while (k <= ss){cnt++;v[cnt] = vv * k;w[cnt] = ww * k;ss -= k;k *= 2;}if (ss > 0){cnt++;v[cnt] = vv * ss;w[cnt] = ww * ss;}}n = cnt;for (int i = 1; i <= n; ++i){for (int j = m; j >= v[i];--j){dp[j] = max(dp[j], dp[j - v[i]] + w[i]);}}cout << dp[m] << endl;}signed main()
{std::ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);int t;Solve();
}

5.分组背包

分组背包acwing

#include<bits/stdc++.h>
using  namespace std;
#define int long long
typedef long long ll;
#define endl '\n'
#define int long long
const int N = 2e5 + 5;int dp[N];
int v[N], w[N];
int cnt[N];void Solve() {int cnt;int n, m; cin >> n >> m;for (int k = 0; k < n; ++k){int s; cin >> s;cnt = 0;for (int i = 1; i <= s; ++i)cin >> v[i] >> w[i];for (int i =m; i >=0; --i){for(int j=1;j<=s;++j)if (i - v[j] >= 0)dp[i] = max(dp[i], dp[i - v[j]] + w[j]);}}cout << dp[m]<< endl;}signed main()
{std::ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);int t;Solve();
}

动态规划DP (update)相关推荐

  1. 第4课 防卫导弹(第十章 动态规划--DP)

    //progream p10_04 /* 第4课 防卫导弹(第十章 动态规划--DP)  (<聪明人的游戏--信息学探秘 提高篇>) https://blog.csdn.net/weixi ...

  2. 动态规划dp(带模板题の超易懂版):01背包,完全背包,分组背包,多重背包,混合背包

    动态规划dp(带模板题の超易懂版):01背包,完全背包,分组背包,多重背包 01背包 && 完全背包 && 分组背包 の 视频教程:https://www.bilibi ...

  3. 【习题详解】动态规划DP:硬币游戏 蛋糕 游荡的奶牛 决斗

    动态规划DP 硬币 蛋糕塔 游荡的奶牛 格斗 硬币 题目描述 农夫约翰的奶牛喜欢玩硬币游戏,因此他发明了一种称为"Xoinc"的两人硬币游戏. 初始时,一个有N(5 <= N ...

  4. 动态规划: dp+递推——确定动态矩阵dp含义,确定每个状态下面临的选择和对结果值影响,选择符合题意的作为结果存储在dp中

    1.动态规划:每一个状态一定是由之前的状态推导出来的,通过总结归纳发现递推关系 2.解决动态规划问题的步骤: 确定dp数组(dp table)以及下标的含义: 每个单元内 题目所求的值,一维.二维 确 ...

  5. 《强化学习》中的 时序差分学习 Temporal-Difference Learning (基于与动态规划 DP 、蒙特卡洛方法 MC 的对比)

    前言: 学习了 Sutton 的<强化学习(第二版)>中时序差分学习的"预测"部分内容.前两章中,书介绍了 动态规划 与 蒙特卡洛方法 ,我们从二者与 时序差分学习 的 ...

  6. Datawhale编程——动态规划DP

    0-1背包问题 问题:有n个物品,第i个物品价值为vi,重量为wi,其中vi和wi均为非负数,背包的容量为W,W为非负数.现需要考虑如何选择装入背包的物品,使装入背包的物品总价值最大. 针对这个经典的 ...

  7. HDU2571 命运【动态规划DP】

    命运 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission ...

  8. 算法技能树2-蓝桥杯-python实现测试次数(摔手机)-动态规划(DP)

    文章目录 1.题目描述 2.python解题 1.知识点总结 1.题目描述 x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机. 各大厂商也就纷纷推出各种耐摔型手机.x星球的质监局规 ...

  9. 动态规划(dp)总结

    问题 T: [动态规划]质数和分解 题目描述 任何大于1的自然数n,都可以写成若干个大于等于2且小于等于n的质数之和的形式(包括只有一个数构成的和表达式的情况),并且可能有不止一种质数和的形式.例如9 ...

最新文章

  1. kvm虚拟机vnc配置
  2. 海归技术大佬:硅谷科技公司到底牛在哪里?讲透“奈飞文化”8个原则!
  3. SIMD(MMX/SSE/AVX)变量命名规范心得
  4. linux三 gdb/makefeile/io
  5. E:VUE 插件 开发与使用 (一)
  6. php 把一个数组分成有n个元素的二维数组的算法
  7. 仅需1秒!搞定100万行数据:超强Python数据分析利器
  8. vacode允许c_使用VS code编译运行C,C++,Java程序
  9. WPF版的Dock控件第二版完成
  10. 以下内容被锁定不能编辑:mxh983 ph6527 zyt2538 zyt9276 zy2674 zyt4372 zyt8731 zyt2832求解
  11. python三国演义人物出场统计
  12. vueJs写一个分页
  13. windows 下用开源流媒体压力测试工具 rtmpstress 测试RTMP媒体服务器负载性能
  14. 走近澳洲------个人所得税篇
  15. mysql8.0约束性语语句(主码、外码、NOT NULL/NULL、DEFAULT、UNIQUE、CHECK)
  16. Python接口测试实战1(下)- 接口测试工具的使用
  17. 计算机网络 组网试验,计算机网络 路由器组网实验报告.doc
  18. GBase 8s 因更换网络导致的908错误
  19. 05_同步对象SYNC的基本概念
  20. Web前端 HTML常用标签 文本格式化标签 图像标签

热门文章

  1. Android启动优化实战(有效降低APP启动时间)
  2. Cloudflare TV 全新亮相
  3. 华清远见C语言学习心得
  4. c语言入门报告,c语言学习心得报告
  5. JDK中的开发工具详解
  6. 量子计算机可以计算葛立恒数,葛立恒数
  7. Kali制作一个钓鱼网站
  8. DWMAC网卡的相关兼容
  9. Android模拟器Genymotion安装及使用教程详解
  10. 我只喜欢你,我不去爱你