DP 动态规划 —数楼梯
今天本蒟蒻来给各位讲讲DP这个鬼东西
缩丝话,DP约等于递推
但我们今天不讲递推
下面进入浓重的精彩时刻
讲理论
这是(cao)好(ni)东(ma)西(de)
1.最优子结构
当问题的最优解包含了其子问题的最优解时,称该问题具有最优子结构性质。问题的最优子结构性质提供了该问题可用动态规划算法求解的重要线索。
在动态规划算法中,利用问题的最优子结构性质,以自底向上的方式递归地从子问题的最优解逐步构造出整个问题的最优解。2.重叠子问题
可用动态规划算法求解的问题应具备的另一个基本要素是子问题的重叠性质。在用递归算法自顶向下求解问题时,每次产生的子问题并不总是新问题,有些子问题被反复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只解一次,而后将其解保存在一个表格中,当再次需要此子问题时,只要简单地用常数时间查看一下结果。通常,不同的子问题个数随问题的大小呈多项式增长。因此,用动态规划算法通常只需要多项式时间,从而获得较高的解题效率。
这一串没啥用 (看了没关系)
简单DP呢
其实就是几个循环
加上一个状态转移式
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
dp[i]=max(d[i-1],dp[i]);
}
}
(这是模板可在此上添加)
下面来一道智障(天才)题
洛谷OJ 数楼梯
题意大概如下
楼梯有 N(0<N<=5000) 阶,上楼可以一步上一阶,也可以一步上二阶。
编一个程序,计算共有多少种不同的走法。
这是一道简单的DP题
其实也可以用其他方法解决
但我们尽量用DP
状态转移式:dp[k][i]=dp[k-1][i]+dp[k-2][i];
下面附上完整代码(注:本题要用高精度)
#include<bits/stdc++.h>
using namespace std;
int n,len=1,dp[305][305];
void find(int k){
int i;
for(i=1;i<=len;i++)
dp[k][i]=dp[k-1][i]+dp[k-2][i];
for(i=1;i<=len;i++)
if(dp[k][i]>=10){
dp[k][i+1]+=dp[k][i]/10;
dp[k][i]=dp[k][i]%10;
if(dp[k][len+1])len++;
}
}
int main(){
freopen("step.in","r",stdin);
freopen("step.out","w",stdout);
int i;
scanf("%d",&n);
dp[1][1]=1;
dp[2][1]=2;
for(i=3;i<=n;i++)
find(i);
for(i=len;i>=1;i--)
printf("%d",dp[n][i]);
return 0;
}
喜欢的大佬可以一键三连哦,有问题请大佬指出
本蒟蒻向大佬90°鞠躬
谢谢!