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

转自: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代码  

  1. #include <iostream>  
  2. #include <cstring>  
  3. #include <algorithm>  
  4. #include <vector>  
  5. using namespace std;  
  6.   
  7. int dp[105][105], board[105][105];  
  8.   
  9. int dfs( int i, int j );  
  10. int main()  
  11. {  
  12.     freopen( “test.txt”“r”, stdin );  
  13.   
  14.     int T, m, n;  
  15.     char name[50];  
  16.     cin>>T;  
  17.   
  18.     while( T– )  
  19.     {  
  20.         memset( dp, -1, sizeof( dp ) );  
  21.         memset( board, 1, sizeof( board ) );  
  22.   
  23.         cin>>name>>m>>n;  
  24.         forint i = 1; i <= m; i++ )  
  25.         {  
  26.             forint j = 1; j <= n; j++ )  
  27.             {  
  28.                 cin>>board[i][j];  
  29.             }  
  30.         }  
  31.   
  32.         int ans = 0;  
  33.   
  34.         forint i = 1; i <= m; i++ )  
  35.         {  
  36.             forint j = 1; j <= n; j++ )  
  37.             {  
  38.                 ans = max( ans, dfs( i, j ) );  
  39.             }  
  40.         }  
  41.           
  42.         cout<<name<<“: “<<ans<<endl;  
  43.           
  44.   
  45.     }  
  46.   
  47.     return 0;  
  48. }  
  49.   
  50. int dx[4] = { -1, 0, 1, 0 };  
  51. int dy[4] = { 0, -1, 0, 1 };  
  52. int dfs( int i, int j )  
  53. {  
  54.     if( dp[i][j] >= 0 )  
  55.         return dp[i][j];  
  56.       
  57.     int temp = 1;  
  58.     forint k = 0; k < 4; k++ )  
  59.     {  
  60.         if( board[i + dx[k]][j + dy[k]] < board[i][j] )  
  61.             temp = max( temp, dfs( i + dx[k], j + dy[k] ) + 1 );  
  62.     }  
  63.   
  64.     return (dp[i][j] = temp);  
  65. }  
    原文作者:动态规划
    原文地址: https://blog.csdn.net/chengxingabc/article/details/50828600
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞