zoukankan      html  css  js  c++  java
  • 动态规划①——记忆化搜索

    首先的首先,必须明白动态规划(DP)以后很有用很有用很有用很有用……
    首先的其次,必须明白:动规≈搜索=枚举

    一、最简单的记忆化搜索(应该可以算DP)

    题目(来自洛谷OJ)http://www.luogu.org/problem/show?pid=1434#

    【不麻烦大家自己找了】
    题目描述 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(从24开始,在1结束)。当然25-24-23―┅―3―2―1更长。事实上,这是最长的一条。
    输入输出格式 Input/output
    输入格式:
    输入的第一行为表示区域的二维数组的行数R和列数C(1≤R,C≤100)。下面是R行,每行有C个数,代表高度(两个数字之间用1个空格间隔)。
    输出格式:
    输出区域中最长滑坡的长度。


    很明显(经典)的搜索题目,你可以从任意一点开始搜索可以滑多远,最后找出最大值。
    呵呵……时间复杂度不忍直视
    所以你可以这么考虑:从一个点开始能滑的最大距离是确定不变的,所以可以用f[x,y]记录下来,并用这个数据推算出其他数据f[x-1,y],f[x+1,y],f[x,y-1],f[x,y+1]。
    所以,开始吧!
    AC程序:

     1 var n,m,i,j,ma:longint;a,f:array[1..100,1..100]of longint;//n m规模;i j循环变量; ma自然是最大值;a记录输入数据(地势高度);f记录从这个点开始能滑多远
     2 function max(a,b:longint):longint;begin if a>b then exit(a) else exit(b);end;//比较两数大小
     3 function find(x,y:longint):longint;//从(x,y)开始能滑多远
     4 var s:longint;
     5 begin
     6   if f[x,y]>0 then exit(f[x,y]);   //已知,直接调用
     7   s:=0;                            //未知,重新搜索
     8   if(x>1)then                                                 //上下左右找最大,别忘边界
     9   if a[x-1,y]<a[x,y] then s:=find(x-1,y);
    10   if(y>1)then
    11   if a[x,y-1]<a[x,y] then s:=max(s,find(x,y-1));
    12   if(x<n)then
    13   if a[x+1,y]<a[x,y] then s:=max(s,find(x+1,y));
    14   if(y<m)then
    15   if a[x,y+1]<a[x,y] then s:=max(s,find(x,y+1));
    16   f[x,y]:=s+1;                    //记忆,别忘+1,否则必0
    17   exit(s+1);                      //同上
    18 end;
    19 begin
    20   readln(n,m);
    21   for i:=1 to n do
    22   for j:=1 to m do
    23   read(a[i,j]);
    24   ma:=0;
    25   for i:=1 to n do
    26   for j:=1 to m do
    27   ma:=max(ma,find(i,j));     //看似复杂度高,其实find(1,1)后整一路的数据都已记录好,直接调用
    28   writeln(ma);
    29 end.
  • 相关阅读:
    学习软件工程的个人总结
    结对编程——黄金点游戏
    读取程序字符,行数,单词的个人程序
    c#代码分析
    Visual Studio2013的安装过程及练习测试
    小学三年级出题程序
    超级课程表的个人评价
    对软件工程的个人困惑
    个人附加作业
    个人最终总结
  • 原文地址:https://www.cnblogs.com/wanglichao/p/4395826.html
Copyright © 2011-2022 走看看