dp訓練計劃——hdu1078記憶化搜索

題目鏈接:https://vjudge.net/problem/HDU-1078

題目大意:

有一種遊戲是的玩法是這樣的:
有一個n*n的格子,每個格子有一個數字。
遵循以下規則:
1. 玩家每次可以由所在格子向上下左右四個方向進行直線移動,每次移動的距離不得超過m
2. 玩家一開始在第一行第一列,並且已經獲得該格子的分值
3. 玩家獲得每一次移動到的格子的分值
4. 玩家下一次移動到達的格子的分值要比當前玩家所在的格子的分值要大。
5. 遊戲所有數字加起來也不大,保證所有數字的和不會超過int型整數的範圍
6. 玩家僅能在n*n的格子內移動,超出格子邊界屬於非法操作
7. 當玩家不能再次移動時,遊戲結束
現在問你,玩家所能獲得的最大得分是多少?

Input

有多組測試數據
每組測試樣例第一行是兩個整數n,m (1≤n≤100)(1≤m≤100),當n和m都是-1時爲程序結束標誌,直接退出即可
之後n行,每行n個數字,描述n*n的格子裏的數字

Output

對於每組測試數據輸出一行,這一行僅有一個整數,代表玩家所能獲得的最高得分

Sample Input

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

Sample Output

37

題解:

一道經典的記憶化搜索題。

狀態:dp[i][j]表示從(i,j)出發的最高的分。

狀態轉移方程:dp[i][j]=max(dp[i][j],dp[x][y]+a[i][j]),保證能夠從(i,j)到達(x,y),且(x,y)合法。

記憶化搜索比較好寫,就只寫了記憶化搜索的代碼實現。

#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<queue>
#define PI atan(1.0)*4
#define E 2.718281828
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define debug printf("ac\n");
using namespace std;
inline int read()
{
    int a=0,b=1;
    char c=getchar();
    while(c<'0'||c>'9')
    {
        if(c=='-')
            b=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9')
    {
        a=(a<<3)+(a<<1)+c-'0';
        c=getchar();
    }
    return a*b;
}
const int INF = 0x3f3f3f3f;
const int N=2e3+7;
int dp[N][N],a[N][N];
int n,m;
int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
int dfs(int x,int y){
    if(dp[x][y]!=-1) return dp[x][y];
    dp[x][y]=a[x][y];
    rp(i,1,m){
        rp(j,0,3){
            int xx=x+dir[j][0]*i;
            int yy=y+dir[j][1]*i;
            if(xx>=n+1||xx<=0||yy>=n+1||yy<=0) continue;
            if(a[xx][yy]<=a[x][y]) continue;
            dp[x][y]=max(dp[x][y],a[x][y]+dfs(xx,yy));
        }
    }
    return dp[x][y];
}
int main(){
    while(~scanf("%d%d",&n,&m)){
        if(n==-1&&m==-1) break;
        rp(i,1,n) rp(j,1,n) a[i][j]=read();
        mst(dp,-1);
        dfs(1,1);
        printf("%d\n",dp[1][1]); 
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章