集训第五周动态规划 I题 记忆化搜索

Description

Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子

 1  2  3  4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9

一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。

Input

输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。

Output

输出最长区域的长度。

Sample Input

5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

Sample Output

25

记忆化搜索当然也还是搜索,只不过在普通的搜索上做了一些优化,因为使用的是动态规划的方法进行的优化,使得它看起来更像DP。首先考虑如果这道题我们只是用普通搜索的方法做,那么就是从某一点开始搜索,一直搜索到最低点,不可以扩展的地方,记录下下滑的长度,那个某一点当然是不可预知的,所以得枚举,也就是说图中的每一点都要搜上一遍,请注意图最大是100*100的,超时肯定是不必说的

所以可以考虑使用dp做,dp比递归好的一个地方在于它解决了重叠子问题,这道题存在很多重叠子问题是不必说的,例如我从10出发,搜到了一条路,下一次我从25出发,等我到达10这一点时,虽然我以前走过这一条路,可是并没有把这一条路记录下来,所以还得重新再走上一遍,这样的重叠问题越多,时间浪费也就越严重,这样的浪费导致了指数级的时间复杂度,是很恐怖的

所以可以使用book【i】【j】(book在英文中有标记的意思)表示从第i行j个开始滑所能下滑的高度

那么动态规划方程为dp(i,j)=max{dp(i-1,j),dp(i+1,j),dp(i,j-1),dp(i,j+1),这些点的高度必须小于i行j列这个点的高度,否则不予考虑}+1

#include"iostream"
#include"cstring"
using namespace std;

const int maxn=110;

int m,n,book[maxn][maxn],a[maxn][maxn];
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};

void Init()
{
    for(int i=1;i<=m;i++)
    for(int j=1;j<=n;j++)
    cin>>a[i][j];
    memset(book,-1,sizeof(book));
}

int dp(int i, int j)
{
    int k, ni, nj;
    if (book[i][j] > 0) return book[i][j];
    book[i][j] = 1;
    for (k = 0; k < 4; ++k)
    {
        ni = i + dir[k][0];
        nj = j + dir[k][1];
        if(ni>=1&&ni<=m&&nj>=1&&nj<=n&&a[i][j]>a[ni][nj]&&dp(ni,nj)+1>book[i][j])
        book[i][j] = book[ni][nj] + 1;
    }
    return book[i][j];
}

void Work()
{
    int ans=-1;
    for(int i=1;i<=m;i++)
    for(int j=1;j<=n;j++)
    if(dp(i,j)>ans) ans=book[i][j];
    cout<<ans<<endl;
   // dp(3,3);
   /* for(int i=1;i<=m;i++)
    {
    for(int j=1;j<=n;j++) cout<<book[i][j]<<" ";
    cout<<endl;
    }*/
}

int main()
{
    while(cin>>m>>n)
    {
     Init();
     Work();
    }
    return 0;
}

HOLLO

				
时间: 2024-08-12 10:10:26

集训第五周动态规划 I题 记忆化搜索的相关文章

集训第五周动态规划 H题 回文串统计

Hrdv is interested in a string,especially the palindrome string.So he wants some palindrome string.A sequence of characters is a palindrome if it is the same written forwards and backwards. For example, 'abeba' is a palindrome, but 'abcd' is not.A pa

集训第五周动态规划 G题 回文串

Description A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a program which, given a string, determines the minimal number of characters to be inserted into t

集训第五周动态规划 F题 最大子矩阵和

Given a two-dimensional array of positive and negative integers, a sub-rectangle is any contiguous sub-array of size 1*1 or greater located within the whole array. The sum of a rectangle is the sum of all the elements in that rectangle. In this probl

集训第五周动态规划 J题 括号匹配

Description We give the following inductive definition of a “regular brackets” sequence: the empty sequence is a regular brackets sequence, if s is a regular brackets sequence, then (s) and [s] are regular brackets sequences, and if a and b are regul

集训第五周动态规划 K题 背包

Description Now you are asked to measure a dose of medicine with a balance and a number of weights. Certainly it is not always achievable. So you should find out the qualities which cannot be measured from the range [1,S]. S is the total quality of a

poj 1579(动态规划初探之记忆化搜索)

Function Run Fun Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 17843   Accepted: 9112 Description We all love recursion! Don't we? Consider a three-parameter recursive function w(a, b, c): if a <= 0 or b <= 0 or c <= 0, then w(a, b

poj 1088 动态规划+dfs(记忆化搜索)

滑雪 Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道载一个 区域中最长底滑坡.区域由一个二维数组给出.数组的每个数字代表点的高度.下面是一个例子 1 2 3 4 5 16 17 18 19 6

【动态规划】【记忆化搜索】CODEVS 最小和 CodeVS原创

f(l,r,i)表示第i段截第l位到第r位时,当前已经得到的价格最小值,可以很显然地发现,这个是没有后效性的,因为对之后截得的段都不造成影响. 注意水彩笔数=1的特判. 递归枚举当前段的r求解(∵l是前一段的r+1),因为很多状态重复,所以可以记忆化. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int save[9][9][9],m,n,we

【动态规划】【记忆化搜索】【搜索】CODEVS 1262 不要把球传我 2012年CCC加拿大高中生信息学奥赛

可以暴力递归求解,应该不会TLE,但是我们考虑记忆化优化. 设f(i,j)表示第i个数为j时的方案数. f(i,j)=f(1,j-1)+f(2,j-1)+……+f(i-1,j-1) (4>=j>=1),从f(n,4)开始递归求解就行. 但是考虑到状态最多只有n*4种,所以记忆化掉吧. 初始化:f(i,1)=1 (1<=i<=n-3) 1 #include<cstdio> 2 using namespace std; 3 int n; 4 long long memory