滑雪
滑雪
(二维数组的最长子序列问题)
1.状态表示:
集合:所有从dp(i,j)这个点开始滑的路径长度
属性:max
2.状态计算:
然后检测该点四周的点 如果可以滑动到其他的点
那么该点的最大滑动长度 就是其他可以滑到的点的滑动长度+1
dp[i][j] = max(dp[i][j-1], dp[i][j+1],dp[i-1][j],dp[i+1][j])
动态规划思想和一维求最长子序列没什么变化。
这题坑就坑在求\(dp [ i ] [ j ]\) 时 ,不能保证\(dp[i][j-1], dp[i][j+1],dp[i-1][j],dp[i+1][j]\),这四个都已经被赋值,所以我们要对这四个点进行判断,如果这个点没有被赋值,就递归调用先去给这个点赋值,如果这个点已经被赋值了,就直接用。
#include <iostream>
using namespace std;
const int N=350;
int a[N][N];
int dp[N][N];
int n,m;
int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};
int dfs(int x,int y){
if(dp[x][y]!=0) return dp[x][y];
for(int k=0;k<4;k++){
int i=x+dx[k];
int j=y+dy[k];
if(i>=0&&i<n&&j>=0&&j<m&&a[i][j]<a[x][y]){
dp[x][y]=max(dp[x][y],dfs(i,j)+1);
}
}
return dp[x][y];
}
int main(){
int mm=0;
cin>>n>>m;
for(int i=0 ;i<n;i++)
for(int j=0;j<m;j++)
cin>>a[i][j];
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
mm=max(mm,dfs(i,j));
}
}
cout<<mm+1<<endl;
return 0;
}

浙公网安备 33010602011771号