您的位置:首页 > 其它

用“动态规划”解决最长滑雪道问题

2014-09-15 16:00 204 查看
转自:http://qu66q.iteye.com/blog/2072272

题目大意:

给你一个矩阵,当做滑雪场,矩阵的每个单元中的数代表高度,滑雪者只能从高的滑到低的地方,且方向只能是上,下,左和右,问滑雪者最长能滑几个单元?



解题思路:

该题本质上就是求矩阵上的最长严格连续递减(或递增)序列,即序列中的元素不能相等,而且前后之间必须相邻。该题属于动态规划问题,要用到递归。

已找递减序列为例,设dp[i][j]表示第i,j点所构成的序列有多长,求这个值,只需要对其上,下,左和右四个方向进行比较就可以,设board表示题目给的矩阵,dfs( i , j )表示求第i,j个点构成的序列长度,则可以得到

若board[i][j] > board[i-1][j], 则dp[i][j] = dp[i-1][j] + 1, 而dp[i-1][j]可以用递归求出,则状态转移方程为:

dp[i][j] = dfs( i-1 , j ) + 1;

但是还不够,要对board[i][j]四个方向都计算一遍,取最大的,所以使用

int dx[4] = { -1, 0, 1, 0 };

int dy[4] = { 0, -1, 0, 1 };

然后进行一次循环,取出最大的值赋给dp[i][j],所以最终的状态转移方程为:

temp = max( temp, dfs( i + dx[k], j + dy[k] ) + 1 );

代码:

Cpp代码


#include <iostream>

#include <cstring>

#include <algorithm>

#include <vector>

using namespace std;



int dp[105][105], board[105][105];



int dfs( int i, int j );

int main()

{

freopen( "test.txt", "r", stdin );



int T, m, n;

char name[50];

cin>>T;



while( T-- )

{

memset( dp, -1, sizeof( dp ) );

memset( board, 1, sizeof( board ) );



cin>>name>>m>>n;

for( int i = 1; i <= m; i++ )

{

for( int j = 1; j <= n; j++ )

{

cin>>board[i][j];

}

}



int ans = 0;



for( int i = 1; i <= m; i++ )

{

for( int j = 1; j <= n; j++ )

{

ans = max( ans, dfs( i, j ) );

}

}



cout<<name<<": "<<ans<<endl;





}



return 0;

}



int dx[4] = { -1, 0, 1, 0 };

int dy[4] = { 0, -1, 0, 1 };

int dfs( int i, int j )

{

if( dp[i][j] >= 0 )

return dp[i][j];



int temp = 1;

for( int k = 0; k < 4; k++ )

{

if( board[i + dx[k]][j + dy[k]] < board[i][j] )

temp = max( temp, dfs( i + dx[k], j + dy[k] ) + 1 );

}



return (dp[i][j] = temp);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: