记忆化dfs(爱吃奶酪的肥老鼠)

题目描述

PIPI家里来了一只肥老鼠!!!
它的活动区域在一个n*n的方格矩阵中,其中每个方格上都一些奶酪,肥老鼠很懒,当它在一个方格吃完奶酪的时候,他最多往上下左右其中一个方向直走k步去找下一块奶酪。肥老鼠也很饿,当它在一个方格吃完奶酪之后,他的下一个目标方格的奶酪必须比当前的奶酪大。现在肥老鼠从(0,0)出发,请问: 肥老鼠最多能吃到多少奶酪?

输入

输入包含多组测试用例。
对于每组测试用例,第一行包含两个数字n和k(1<=n,k<=100)。
接下来输入包含一个 n*n的方格矩阵(不超过10000)。
以一对 -1 -1结束所有输入。

输出

对于每组测试用例,输出肥老鼠能够吃到的最多奶酪数。

样例输入

3 1
1 2 5
10 11 6
12 12 7
-1 -1

样例输出

37

一个方向最多走k步,显然要用动态规划

#include 
#include 
using namespace std;
int n,k;
int maze[105][105],dp[105][105];
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int dfs(int x,int y){
    int sum=0;
    if(dp[x][y]) return dp[x][y];
    for(int i=0;i<4;i++)
    for(int j=1;j<=k;j++){
        int xx=x+dir[i][0]*j;
        int yy=y+dir[i][1]*j;
        if(xx>=0&&yy>=0&&xx<n&&yy<n&&maze[xx][yy]>maze[x][y]){
            sum=max(sum,dfs(xx,yy));
        }
    }
dp[x][y]=sum+maze[x][y];
return dp[x][y];
}

int main(){
int i,j;
while(scanf("%d %d",&n,&k)){
    if(n==-1||k==-1) break;
    for(i=0;i<n;i++)
    for(j=0;j<n;j++){
        scanf("%d",&maze[i][j]);
        dp[i][j]=0;
    }
    dfs(0,0);
    printf("%d\n",dp[0][0]);
}
return 0;
}

1093: 滑雪

题目描述
PIPI喜欢滑雪这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。PIPI想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子
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更长。事实上,这是最长的一条。
输入
多组数据
输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。
接下来R行,每行有C个整数,代表高度h,0<=h<=10000。
输出
输出最长区域的长度。
样例输入

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

样例输出

25

#include 
#include 
int R,C;
int h[100][100],dp[100][100];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int getdp(int x,int y){
    int i;
    if(dp[x][y]!=-1) return dp[x][y];
    dp[x][y]=0;
    for(i=0;i<4;i++){
        int xx=x+dir[i][0];
        int yy=y+dir[i][1];
        if(xx>=0&&xx<R&&yy>=0&&yy<C&&h[xx][yy]<h[x][y])
            dp[x][y]=getdp(xx,yy)+1>dp[x][y]?getdp(xx,yy)+1:dp[x][y];
    }
return dp[x][y];
}
int main(){
    int i,j,ans;

while(scanf("%d %d",&R,&C)!=EOF){
        memset(dp,-1,sizeof(dp));
    for(i=0;i<R;i++)
        for(j=0;j<C;j++)
        scanf("%d",&h[i][j]);
        ans=0;
     for(i=0;i<R;i++)
        for(j=0;j<C;j++){
        getdp(i,j);
        ans=ans>dp[i][j]?ans:dp[i][j];
        }
        printf("%d\n",ans+1);
}
return 0;
}

你可能感兴趣的:(记忆化dfs(爱吃奶酪的肥老鼠))