什么是动态规划?
动态规划算法是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决。
…是不是感觉太抽象┭┮﹏┭┮,下面有归纳
所有的动态规划问题解题:==两个步骤:要明确状态,转移。==结合例题分析
例题解析:
例题一:数字三角形
试题内容:
图1给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。
注意:路径上的每一步只能从一个数走到下一层上和它最近的左边的那个数或者右边的那个数。
input
输入的是一行是一个整数N (1 < N <= 100),给出三角形的行数。下面的N行给出数字三角形。数字三角形上的数的范围都在0和100之间。
output
输出最大的和。
Sample Input
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
Sample Output
30
套路过程,解题分析:
解题两步走:
1 定义状态:
- f[i][j]表示从(1,1)出发走到(i,j) 所有路径的最大和。例如:
7
3 8
8 1 0
求f[3][2] 就是求从7这个数到1这个数所有路径的最大和:f[3][2] =max(7+3+1,7+8+1)=16. - 最后结果是:max{F[n][1…n]}
2 如何转移:
- 考虑哪些状态对f[i][j]这个状态有影响。每一个的
影响元素
两个:(i-1,j)->(i,j) ; (i-1,j-1) 如何转移
:f[i][j]=max{f[i-1][j],f[i-1][j-1]}+a[i][j],把(1,1)到(i,j)的路径分为两类,(1,1)->(i-1,j)->(i,j) 和(1,1)->(i-1,j-1)->(i,j)
思路重点:
对于状态
- 初始状态f[1][1] = a[1][1],其余为==-inf或者0==(因为题目中没有负数),因为有些是处于非法位置,例如:例题中的8的位置的正上方是没有数字的,因此要让它正上方的值为-inf,这样就f[2][2] = {7,-inf}+a[2][2]=7+8=15;
- 答案在那里取:max{F[n][1]…{F[n][n]}
对于转移 - 要注意转移的顺序,从上到下,从左到右
解题方法
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int mMax = 110;
int a[mMax][mMax],f[mMax][mMax];
int n,ans;
void dp(){
for(int i=2;i<=n;i++){
for(int j=1;j<=i;j++){
f[i][j]=max(f[i-1][j-1],f[i-1][j])+a[i][j];
if(ans<f[i][j]) ans = f[i][j];
}
}
}
int main(){
scanf("%d",&n);
memset(a,0,sizeof(a));
memset(f,0,sizeof(f));
ans = 0;
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
cin>>a[i][j];
}
}
f[1][1] = a[1][1];
dp();
printf("%d\n",ans);
return 0;
}
勉励
打卡第四天,加油ヾ(◍°∇°◍)ノ゙
感悟不能急于求成,要稳扎稳打
如果觉得我的文章对你有所帮助与启发,点赞给我个鼓励吧(づ ̄3 ̄)づ╭❤~
关注我和我一起共勉加油
吧!
如果文章有错误,还望不吝指教!