dp by zhx
dp是什么
动态规划,三要素:状态、转移,初始化。状态是最基础的,转移是状态之间的关系,初始化是状态的边界,如何设计状态。
引入-1.-1 P1216 [IOI1994]数字三角形
给一个数字三角形,可以向下或向右下走,试问路径数字和的最大值。
状态:
-1.-1.5 数字三角形2
若将路径数字和的最大值变为路径数字和
怎么做?我们可以加维度!设置三维状态,把右边变化的量加进去!
代码:
#include <bits/stdc++.h>
#define int long long
const int MAXN=105;
int a[MAXN][MAXN],dp[MAXN][MAXN][MAXN];
int n;
signed main(){
std::cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
std::cin>>a[i][j];
}
}
dp[1][1][a[1][1]%100]=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
for(int k=0;k<=99;k++){
if(dp[i-1][j][k]||dp[i-1][j-1][k])dp[i][j][(k+a[i][j])%100]=1;
}
}
}
int ans=-1;
for(int i=1;i<=n;i++){
for(int j=0;j<=99;j++){
if(dp[n][i][j]){
ans=std::max(ans,j);
}
}
}std::cout<<ans<<'\n';
return 0;
}
-1.-2 斐波那契数列
给定
1.用定义推
f[0]=0,f[1]=1;
for(int i=1;i<=n;i++)f[i]=(f[i-1]+f[i-2])%mod;
2.用自己更新别人
f[0]=0,f[1]=1;
for(int i=0;i<=n;i++)f[i+1]+=f[i],f[i+2]+=f[i];
3.记忆化搜索
我们先来爆搜
int dfs(int x){
if(n==0)return 0;
if(n==1)return 0;
f[x]=(f(x-1)+f(x-2));
return f[x];
}
这个东西是
记忆化!
若我们已经求出了一个值,就不需要再求一遍!
int dfs(int x){
if(n==0)return 0;
if(n==1)return 0;
if(g[x])return f[x];
g[x]=1;
f[x]=(f(x-1)+f(x-2));
return f[x];
}
比较简单。
有些 dp 只能用第一种,有些只能用第二种,如现有一个转移
但是如果自己可以快速转移到区间,那么就用第二种。
这是ds优化dp的内容。
记忆化搜索一般在博弈论dp中用到。
dp分类
- 背包dp
- 区间dp
- 树形dp
- 数位dp
- 状压dp
- 插头dp
- 排列dp
- 博弈dp
- 一般dp
一般dp 例题
posted on 2024-05-27 21:04 ScapeGoatTree 阅读(7) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!