zhxのDP讲
时间:2021-07-17
本文章向大家介绍zhxのDP讲,主要包括zhxのDP讲使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
DP基础例题
1. 斐波那契数列
f[1]=1;//第0项和第1项
f[0]=0;
//记忆化搜索
int dp(int n)//斐波那契数列第n项
{
//g[i]表示f[i]有没有计算过
if(n<=1)return n;
if(g[n])return f[n];
g[n]=true;
f[n]=dp(n-1)+dp(n-2);
return f[n];//O(fn)
}
//其它求当前
for(int i=2;i<=a;i++)
f[i]=f[i-1]+f[i-2];
//O(n)
//当前求其它
for(int i=0;i<=n;i++)
{
//O(n)
f[i+1]+=f[i];
f[i+2]+=f[i];
}
2. 组合数
for (int i=0;i<=n;i++)
{
C[i][0] = 1;//处理边界
for (int j=1;j<=i;j++)
C[i][j] = C[i-1][j-1] + C[i-1][j];
}
- IOI数字三角形及其系列
状态:f[位][置]=经过的数字之和
f[i][j]:走到 (i,j) 的数字最大和
//滑雪
n行m列
可以走任意四个方向
每走一步需要使得脚底数字变大
最多走几个格子
f[x][y]代表走到(x,y)的最长长度
若:a[x-1][y]>a[x][y];
f[x-1][y]=max(f[x-1][y],f[x][y]+1)
//不正确解,使用自己求其他
//但没有保证当前的位置求出
cin >> n >> m;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
cin >> a[i][j];
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
f[i][j]=1;
for (int x=1;x<=n;x++)
for (int y=1;y<=m;y++)
for (int d=上下左右)
{
int xx = x朝着d走;
int yy = y朝着d走;
if ( (xx,yy)存在 && a[xx][yy] > a[x][y]) f[xx][yy] = max(f[xx][yy],f[x][y]+1);
}
DP三要素:
- 状态
- 转移方程
- 边界条件
DP可加维度
f[i][j](二维)—f[i][j][k](三维)—f[i][j][k][l](四维)
若时间空间过高,削减冗余状态,减少维度
建一个和原来状态相同的数组储存方案或方案数
背包模型
背包DP
01背包
n个物品 背包容积为m
第i个物品体积为vi,价值为wi
需要向背包里装一定的物品,在体积不超限的情况下装价值最高的物品
f[编号][体积]=价值
f[i][j]表示考虑完前i个物品 背包已经使用了j的体积
//01背包
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>v[i]>>w[i];
}
//v体积 w价值
for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++)
{
//考虑求f[i][j]
f[i][j]=f[i-1][j];//第i个物品不选
if(j>=v[i])
f[i][j]=max(f[i][j],f[i-1][j-v[i]]+w[i])
}
例题采药
无穷背包
n种物品 背包容积为m
每种物品数量不限
第i个物品体积为vi,价值为wi
f[i][j]表示考虑完前i种类物品 背包已经使用了j的体积
//无穷背包
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>v[i]>>w[i];
}
//v体积 w价值
for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++)
{
//考虑求f[i][j]
f[i][j]=f[i-1][j];//第i个物品不选
if(j>=v[i])
f[i][j]=max(f[i][j],f[i][j-v[i]]+w[i])
}
例题疯狂的采药
有限背包(多重背包)
有N种物品和一个容量为T的背包,第i种物品最多有M[i]件可用,价值为P[i],体积为V[i]
求解:选哪些物品放入背包,可以使得这些物品的价值最大,并且体积总和不超过背包容量。
//有限(多重)背包
cin>>n>>m;
int k=0;
//v体积 w价值 u个数
for(int i=1;i<=n;i++)
{
int v_,w_,x_;
cin>>v_>>w_>>x_;
int r=1;
while(x_>=r)
{
k++;
v[k]=v_*r;
w[k]=w_*r;
x_-=r;
r*=2;
}
if(x_!=0){
k++;
v[k]=v_*x_;
w[k]=w_*x_;
}
}
for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++)
for(int k=0;k*v[i]<=j&&k<=u[i];k++){
//考虑如何求f[i][j]
f[i][j]=max(f[i][j],f[i-1][j-kv[i]]+k*w[i]);
}
原文地址:https://www.cnblogs.com/DAIANZE/p/15024698.html
- 13.MySQL(一) 数据库简介mysql安装数据库操作Mysql数据类型存储引擎
- 3314: [Usaco2013 Nov]Crowded Cows
- BZOJ4766: 文艺计算姬
- 14.MySQL(二) 数据之表操作表内容操作Mysql 连接事务外键
- 3450: Tyvj1952 Easy
- SP104 HIGH - Highways
- 1664: [Usaco2006 Open]County Fair Events 参加节日庆祝
- 15.MySQL(三) 索引类型
- 1054: [HAOI2008]移动玩具
- MatrixTree速成
- 1元搭建自己的云服务器&解析域名
- 洛谷P4180 [Beijing2010组队]次小生成树Tree
- 携程开源数据库访问框架
- LOJ #108. 多项式乘法
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Python 为什么用 # 号作注释符?
- Logging with ElasticSearch, Kibana, ASP.NET Core and Docker
- 【DB笔试面试843】在Oracle中,解释GLOBAL_NAMES设为TRUE的用途。
- SpringBoot 返回 json 数据以及数据封装(万字长文)
- 内核级木马与病毒攻防:Linux可执行文件的ELF格式描述
- 「 思考 」 React Hooks 的设计哲学
- JMeter之Json提取器详解
- nodejs 图片处理工具 gm 的使用!
- Java 进程内存分布
- Web 游戏监听浏览器返回点击事件 !
- 权限维持_Linux操作系统后门
- Linux入门学习笔记(一)
- CMD命令笔记总结
- 字典生成神器Crunch
- DC-5靶机渗透实战