最基础的注意重点:初始化+状态转移方程
非常基础的三角形求路径最大值https://www.luogu.com.cn/problem/P1216
#include<iostream>
using namespace std;
int r;
int dp[1001][1001];
int main(){
cin>>r;
for(int i=1;i<=r;i++)
for(int j=1;j<=i;j++)
cin>>dp[i][j];
//初始化左右两斜线
for(int i=2;i<=r;i++){
dp[i][1]+=dp[i-1][1];
dp[i][i]+=dp[i-1][i-1];
}
for(int i=3;i<=r;i++){
for(int j=2;j<i;j++){
dp[i][j]+=max(dp[i-1][j-1],dp[i-1][j]);
}
}
int maxx=-1;
for(int i=1;i<=r;i++)
maxx=max(maxx,dp[r][i]);
cout<<maxx;
}
大朋友的数字https://www.luogu.com.cn/problem/P2008
这道题涉及到的是求最长不下降子序列
这道题的思路是
因为每一个人的分数只由他前边的人决定,所以在一次遍历中可以完成输入数字+计算这个人的分数
num数组装数字,sum数组装分数
1,sum=1
2,j开始循环,1<2,dp[1]+1>dp[2],更新dp,sum=3
5,j开始循环,1<5,dp[1]+1>dp[5],更新dp,sum=6
2<5,dp[2]+1>dp[5],更新dp,sum=8
#include<iostream>
using namespace std;
int n;
int num[10000+10]; //每个人的数字
int sum[10000+10]; //每个人的分数(到这里的最长不下降子序列的和)
int dp[10000+10]; //dp[i]代表到第i个数它的最长子序列长度
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>num[i];
sum[i]=num[i];
for(int j=1;j<i;j++){
if(num[j]<=num[i] && dp[j]+1>dp[i]){
dp[i]=dp[j]+1;
sum[i]=sum[j]+num[i];
}
}
cout<<sum[i]<<" ";
}
}
又上锁妖塔https://www.luogu.com.cn/problem/P2800
自己写的:股票问题那学的思路
#include<iostream>
using namespace std;
//n层
//每层的高度不同
int n;
int height[1000000+5];
//每次可以向上+1或+2
//跳完后必须至少一层
//理解题意,跳跃不花时间,爬楼的话消耗的就是高度的时间
int dp[1000000+5][2];//到第i层时花费的最小时间
//dp[i][0]代表第i层是跳上来的
//dp[i][1]代表第i层是爬的
int main(){
cin>>n;
for(int i=1;i<=n;i++)
cin>>height[i];
dp[1][0]=0;
dp[1][1]=height[1];
dp[2][0]=0;
dp[2][1]=dp[1][0]+height[2];
for(int i=3;i<=n;i++){
//在每一层有两种选择,跳or爬
dp[i][0]=min(dp[i-1][1],dp[i-2][1]);
dp[i][1]=height[i]+min(dp[i-1][1],dp[i-1][0]);
}
cout<<min(dp[n][0],dp[n][1]);
}
优秀的题解:
f[0]=0,因为底层不用爬
要求的是f[7]
#include<bits/stdc++.h>
using namespace std;
int n;
int a[1000005];
int f[1000005];
int main() {
cin>>n;
for(int i=1; i<=n; i++) {
cin>>a[i];
f[i]=1e9;//注意初始化
}
f[n+1]=1e9;
for(int i=1; i<=n+1; i++) {//循环到n+1
f[i]=min(f[i],f[i-1]);
f[i]=min(f[i],f[i-2]);
f[i]=min(f[i],f[i-3]);
f[i]+=a[i];
}
cout<<f[n+1];//输出解
return 0;//愉快的结束
}