线性dp
动态规划步骤:
1.状态表示
用几维度的数组,每一维度的意思。
2.状态计算
状态转移方程
题目:
数字三角形
给定一个如下图所示的数字三角形,从顶部出发,在每一结点可以选择移动至其左下方的结点或移动至其右下方的结点,一直走到底层,要求找出一条路径,使路径上的数字的和最大。
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输入格式
第一行包含整数 n,表示数字三角形的层数。
接下来 n 行,每行包含若干整数,其中第 i 行表示数字三角形第 i 层包含的整数。
输出格式
输出一个整数,表示最大的路径数字和。
数据范围
1≤n≤500
−10000≤三角形中的整数≤10000
输入样例:
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输出样例:
30
查看代码
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[600][600];
int dp[600][600];
int n;
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++){
dp[i][1]=a[i][1]+dp[i-1][1];
for(int j=2;j<i;j++){
dp[i][j]=a[i][j]+max(dp[i-1][j],dp[i-1][j-1]);
}
dp[i][i]=a[i][i]+dp[i-1][i-1];
}
int m=dp[n][1];
for(int i=1;i<=n;i++){
if(m<dp[n][i])m=dp[n][i];
}
cout<<m;
return 0;
}
状态表示:dp[i][j]表示到元素(i,j)的最大路径长
状态计算:
//一般情况
dp[i][j]=a[i][j]+max(dp[i-1][j],dp[i-1][j-1]);
特殊情况
行首元素:
dp[i][1]=a[i][1]+dp[i-1][1];
行末元素:
dp[i][i]=a[i][i]+dp[i-1][i-1];
题目:
最长上升子序列
给定一个长度为 N 的数列,求数值严格单调递增的子序列的长度最长是多少。
输入格式
第一行包含整数 N。
第二行包含 N个整数,表示完整序列。
输出格式
输出一个整数,表示最大长度。
数据范围
1≤N≤1000
−109≤数列中的数≤109
输入样例:
7
3 1 2 1 8 5 6
输出样例:
4
补充知识:
子序列:
从原序列删除一些元素剩余元素组成的序列是子序列。
子串:
要是原序列中连续截取的。
子串的长度:0~总长
这道题输入数字的下标从1开始。
查看代码
#include<bits/stdc++.h>
using namespace std;
long long int a[1200];
long long int f[1200];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
f[i]=1;
for(int j=1;j<=i-1;j++){
if(a[j]<a[i]) f[i]=max(f[i],f[j]+1);
}
}
int m=f[1];
for(int i=1;i<=n;i++){
if(m<f[i]) m=f[i];
}
cout<<m;
return 0;
}
动态规划:
状态表示:
f[i]表示以i结尾的序列长度
最后遍历i=1~n,找最长的子序列长度。
状态计算:
计算f[i]的方法是:
求得0~i-1结尾的子序列长+1,如果这个数比第i个数小就进行这个
if(a[j]<a[i])f[i]=max(f[i],f[j]+1);
注意特殊情况:以每个数字结尾的子序列长最短为1,所以每个数字结尾初始化为1.
标签:数字,--,样例,整数,int,序列,线性,dp From: https://www.cnblogs.com/luckyyaoyao/p/17981332