UVA-10285 Longest Run on a Snowboard (递推)
题目大意:滑雪。给一个二维数组,找出最长的连续下降序列的长度。
题目分析:定义dp(i,j)表示以a[i][j]结尾的最长连续下降序列的长度,则dp(i,j)=max(dp(i-1,j),dp(i+1,j),dp(i,j-1),dp(i,j+1)),重复这个DP过程滚动更新dp数组100次即可(我专门做了一下测试,更新次数在42次及以上时都能AC)。
代码如下:
# include<iostream> # include<cstdio> # include<string> # include<cstring> # include<algorithm> using namespace std; int a[105][105],dp[105][105]; int n,m; string p; int d[4][2]={{-1,0},{1,0},{0,1},{0,-1}}; bool judge(int x,int y) { return x>=0&&x<n&&y>=0&&y<m; } int solve() { for(int i=0;i<n;++i) for(int j=0;j<m;++j) dp[i][j]=1; for(int k=0;k<42;++k){ for(int x=0;x<n;++x){ for(int y=0;y<m;++y){ for(int i=0;i<4;++i){ int nx=x+d[i][0],ny=y+d[i][1]; if(judge(nx,ny)&&a[x][y]>a[nx][ny]&&dp[x][y]+1>dp[nx][ny]) dp[nx][ny]=dp[x][y]+1; } } } } int ans=0; for(int i=0;i<n;++i) for(int j=0;j<m;++j) ans=max(ans,dp[i][j]); return ans; } int main() { int T; scanf("%d",&T); while(T--) { cin>>p; scanf("%d%d",&n,&m); for(int i=0;i<n;++i) for(int j=0;j<m;++j) scanf("%d",&a[i][j]); cout<<p<<": "<<solve()<<endl; } return 0; }