DP全称动态规划,是算法中的重中之重。

目录

  • 背包问题
    • 01背包问题
    • 完全背包
    • 多重背包
    • 分组背包
    • 习题
  • 线性DP
    • 最长上升子序列
    • 最长公共子序列
    • 一个字符串修改后变成另一个字符串的最少步数
  • 区间DP
  • 计数类DP
  • 状态压缩DP
  • 树形DP
  • 记忆化搜索

背包问题


01背包: 每件物品最多只用一次

完全背包: 每件物品有无限个

多重背包 : 每件物品有不同多个

分组背包 : 有多个组,每组内有多个物品,每一个组内只能选一个


01背包问题

//f[i][j] 从前i个物品选,体积不超过j的最大价值
for(int i=1;i<=n;i++)
{for(int j=0;j<=m;j++){f[i][j]=f[i-1][j];if(j>=v[i]) f[i][j]=max(f[i][j],f[i-1][j-v[i]]+w[i]);}
}
cout<<f[n][m];
//空间优化的01背包  f[i] 表示体积不超过i的最大价值
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--){f[j]=max(f[j],f[j-v[i]]+w[i]);}
}
cout<<f[m];

完全背包

for(int i=1;i<=n;i++) cin>>v[i]>>w[i];
for(int i=1;i<=n;i++)
{for(int j=0;j<=m;j++){f[i][j]=f[i-1][j];f(j>=v[i]) f[i][j]=max(f[i][j],f[i][j-v[i]]+w[i]);}
}
cout<<f[n][m]<<endl;
//空间优化for(int i=1;i<=n;i++)for(int j=v[i];j<=m;j++)f[j]=max(f[j],f[j-v[i]]+w[i]);
cout<<f[m]<<endl;

多重背包

//暴力模板
for(int i=1;i<=n;i++) cin>>v[i]>>w[i]>>cnt[i];for(int i=1;i<=n;i++)for(int j=0;j<=m;j++)for(int k=0;k<=cnt[i]&&v[i]*k<=j;k++)f[i][j]=max(f[i][j],f[i-1][j-k*v[i]]+k*w[i]);
cout<<f[n][m];
//二进制优化
#include<bits/stdc++.h>
using namespace std;
const int N=1e3*3+10;
int f[N],v[N],w[N],cnt,n,m;
int main(void)
{cin>>n>>m;for(int i=0;i<n;i++){int v1,w1,c; cin>>v1>>w1>>c;int k=1;while(c>=k){++cnt;v[cnt]=v1*k,w[cnt]=w1*k;c-=k,k*=2;}if(c) {++cnt;v[cnt]=c*v1,w[cnt]=w1*c;}}for(int i=1;i<=cnt;i++){for(int j=m;j>=v[i];j--)f[j]=max(f[j],f[j-v[i]]+w[i]);}cout<<f[m];return 0;
}

分组背包

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int n,m,f[N][N],w[N][N],v[N][N],cnt[N];
int main(void)
{cin>>n>>m;for(int i=1;i<=n;i++){cin>>cnt[i];for(int j=1;j<=cnt[i];j++) cin>>v[i][j]>>w[i][j];}for(int i=1;i<=n;i++){for(int j=0;j<=m;j++){f[i][j]=f[i-1][j];for(int k=1;k<=cnt[i];k++){if(j>=v[i][k]) f[i][j]=max(f[i][j],f[i-1][j-v[i][k]]+w[i][k]);}}}cout<<f[n][m];return 0;
}

习题

2. 01背包问题
3. 完全背包问题
4. 多重背包问题 I
5. 多重背包问题 II
9. 分组背包问题

线性DP

最长上升子序列

//朴素版
for(int i=0;i<n;i++) cin>>h[i];
for(int i=0;i<n;i++)
{f[i]=1;for(int j=0;j<i;j++) if(h[j]<h[i]) f[i]=max(f[i],f[j]+1);
}
int res=0;
for(int i=0;i<n;i++) res=max(res,f[i]);
cout<<res;
//二分+贪心优化版
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,q[N],a[N],len;
int main(void)
{cin>>n;for(int i=0;i<n;i++) cin>>a[i];q[0]=-2*1e9;//哨兵for(int i=0;i<n;i++){int l=0,r=len;while(l<r){int mid=l+r+1>>1;if(q[mid]<a[i]) l=mid;else r=mid-1;}len=max(len,r+1);q[r+1]=a[i];}cout<<len;return 0;
}

最长公共子序列

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int f[N][N],n,m;
char a[N],b[N];
int main(void)
{cin>>n>>m>>a+1>>b+1;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(a[i]!=b[j]) f[i][j]=max(f[i][j-1],f[i-1][j]);else f[i][j]=max(f[i][j],f[i-1][j-1]+1);}}cout<<f[n][m]<<endl;return 0;
}

一个字符串修改后变成另一个字符串的最少步数

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int f[N][N],n,m;
char a[N],b[N];
int main(void)
{cin>>n>>a+1>>m>>b+1;for(int i=1;i<=n;i++) f[i][0]=i;for(int j=1;j<=m;j++) f[0][j]=j;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){f[i][j]=min(f[i-1][j]+1,f[i][j-1]+1);f[i][j]=min(f[i][j],f[i-1][j-1]+(a[i]!=b[j]));}}cout<<f[n][m]<<endl;//f[n][m]字符串a的前n个字符和字符串b的前m个字符相等需要的最小步数return 0;
}

区间DP

计数类DP

状态压缩DP

状压 dp 是动态规划的一种,通过将状态压缩为整数来达到优化转移的目的。

树形DP

记忆化搜索

ACM入门之【DP】相关推荐

  1. C语言oj学生成绩输入和输出,『ACM入门』蓝桥杯ACM训练系统基本输入输出教程

    在介绍训练场的OJ系统之前,首先为大家介绍一下ACM: ACM原代表美国计算机协会,因其举办的ICPC即国际大学生程序设计竞赛而闻名全世界,此项赛事要求学生的在五小时内解决全英文问题,并在效率和速度以 ...

  2. c语言记忆化搜索,HNUSTC语言基础简单数据结构acm入门第一讲搜索.ppt

    C语言基础,简单数据结构,ACM入门讲座搜索部分 Bjut:mark063 2010.10.30 1 Evaluation only. Created with Aspose.Slides for . ...

  3. 硬币找零 acm入门 day4--动态规划dp第一题

    A - 硬币找零 在现实生活中,我们经常遇到硬币找零的问题,例如,在发工资时,财务人员就需要计算最少的找零硬币数,以便他们能从银行拿回最少的硬币数,并保证能用这些硬币发工资.我们应该注意到,人民币的硬 ...

  4. ACM入门及STL简介(转)

    第一章 新手入门 1.      ACM国际大学生程序设计竞赛简介 1)      背景与历史 1970年在美国TexasA&M大学举办了首次区域竞赛,从而拉开了国际大学生程序设计竞赛的序幕. ...

  5. 【转载】ACM入门 .

    初期: 一.基本算法:      (1)枚举. (poj1753,poj2965)      (2)贪心(poj1328,poj2109,poj2586)      (3)递归和分治法.      ( ...

  6. ACM入门指南[转]

    前言: 这篇指南不对ACM/ICPC国际大学生程序设计竞赛进行介绍,计算机学子如果不了解的可以在百度上进行搜索查询,这里介绍的只是一个计算机学生想要在ACM/ICPC里进行发展的初学者.内容比较简单通 ...

  7. ACM入门之【搜索】

    搜索在ACM中是很重要的. 搜索一般分为DFS和BFS两大类,下面又划分很多的小类. 入门习题: 842. 排列数字 843. n-皇后问题 844. 走迷宫 845. 八数码

  8. ACM入门之【读入、输出优化】

    本文主要是基于oiwiki的做的总结,未来也会做一系列的相关文章.如果想继续看的话可以关注专栏. 做这个专栏的目的是因为自己最近开始系统的再打一下基础.于是想写一个专栏便于喜爱ACM的初学者入门. 目 ...

  9. ACM入门及STL简介

    1.       ACM 国际大学生程序设计竞赛简介 1)       背景与历史 1970 年在美国TexasA&M 大学举办了首次区域竞赛,从而拉开了国际大学生程序设计竞赛的序幕.1977 ...

最新文章

  1. [DiscuzNt]整合DiscuzNt论坛目前所发现的小BUG及个人简单解决办法
  2. 一个插排引发的设计思想 (三) 委托与事件
  3. java nextday_Nextday 参数化单元测试(测试用例)设计
  4. ASP.NET中过滤HTML字符串的两个方法
  5. .net core word转pdf_免费在线转换PDF转Word、Word转PDF,办公必备神器
  6. python opengl_Python环境搭建之OpenGL
  7. 2020年学python_Python学习路线图(2020年最新版)
  8. 计算机配置界面在那,在哪里设置关机画面?设置为原来的经典界面?
  9. gettype获取类名_在TypeScript中运行时获取对象的类名
  10. Fiddler快速入门
  11. 华为云数据库GaussDB(for Cassandra)揭秘第二期:内存异常增长的排查经历
  12. 关于在openstack执行nova get-vnc-console命令,无法得到vnc url并提示服务器超时的问题描述...
  13. 高等数学所有符号的写法与读法
  14. ncl 添加点shp文件_NCL绘制中国地图
  15. python爬虫爬取搜狗微信文章(代理池+re从跳转链接中找到真实URL问题)
  16. linux office转换pdf
  17. 正则表达式(正则表达式的方法和属性、正则的修饰符、表达式、元字符、量词)
  18. 关于win10重新安装应用商店(Microsoft Store)的解决方案
  19. vivo手机html有吗,vivo手机有哪些系列?区别是什么?
  20. 不要一个人吃饭---人脉就是钱脉

热门文章

  1. MAT之ELM:ELM实现鸢尾花(iris数据集)种类测试集预测识别正确率(better)结果对比
  2. Scrapy八小时快速入门第一小时:安装,创建与执行我们的Scrapy爬虫
  3. RandomForest:随机森林
  4. ARIMA模型详细讲解
  5. Spring使用笔记(一)Spring简介
  6. 提高ASP.NET应用程序性能的几招方法
  7. 再学 GDI+[79]: 区域(8) - Transform - 区域的 Matrix 变换
  8. linux驱动篇之 driver_register 过程分析(一)
  9. 第四章-数据共享与保护
  10. EOS 源代码解读 (4)交易数据结构