Fzu 2234 牧場物語(DP)
阿新 • • 發佈:2018-11-22
Problem 2234 牧場物語
Accept: 148 Submit: 722
Accept: 148 Submit: 722
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
小茗同學正在玩牧場物語。該遊戲的地圖可看成一個邊長為n的正方形。
小茗同學突然心血來潮要去砍樹,然而,斧頭在小茗的右下方。
小茗是個講究效率的人,所以他會以最短路程走到右下角,然後再返回到左上角。並且在路上都會撿到/踩到一些物品,比如說花朵,錢和大便等。
物品只能被取最多一次。位於某個格子時,如果格子上還有物品,就一定要取走。起點和終點上也可能有物品。
每種物品我們將為其定義一個價值,當然往返之後我們取得的物品的價值和越大越好。但是小茗同學正在認真地玩遊戲,請你計算出最大的價值和。
Input
多組資料(<=10),處理到EOF。
第一行輸入正整數N(N≤100),表示正方形的大小。
接下來共N行,每行N個整數Ai,j(|Ai,j|≤10^9),表示相應對應位置上物品的價值。值為0表示沒有物品。
Output
每組資料輸出一個整數,表示最大價值和。
Sample Input
211 1416 12Sample Output
53思路,記憶化搜尋,這題跟fzu2092很相像,只是地圖大了很多。題目有個限制,每次他都必須走,不能停留在原地,所以我們可以只算x0和y1,因為y0和x1可以通過t算出來。
#include <stdio.h> #include <string.h> #include <string> #include <algorithm> #include <iostream> using namespace std; #define LL long long #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lowbit(x) (x&-x) const int maxn = 105; const LL INF = 1e15+7; //一開始這裡設了0x3f3f3f3f Wa到死 int n; LL dp[maxn][maxn][2*maxn],a[maxn][maxn]; bool vis[maxn][maxn][2*maxn]; int d[] = {0,1}; LL dfs(int x0,int y0,int x1,int y1,int t) { if(t>=2*n-1) return 0; if(x0<1||x0>n||x1<1||x1>n) return -INF; if(y0<1||y0>n||y1<1||y1>n) return -INF; if(vis[x0][y1][t]) return dp[x0][y1][t]; vis[x0][y1][t] = true; LL mx = -INF; mx = max(mx,dfs(x0,y0+1,x1,y1+1,t+1)); mx = max(mx,dfs(x0,y0+1,x1+1,y1,t+1)); mx = max(mx,dfs(x0+1,y0,x1,y1+1,t+1)); mx = max(mx,dfs(x0+1,y0,x1+1,y1,t+1)); dp[x0][y1][t] = mx; if(x0==x1&&y0==y1) dp[x0][y1][t] += a[x0][y0]; else dp[x0][y1][t] += a[x0][y0]+a[x1][y1]; return dp[x0][y1][t]; } LL readint() { LL ret = 0,sgn = 1; char c = getchar(); while (c!='-'&&(c<'0' || c>'9')) c = getchar(); sgn = (c=='-')?-1:1; ret = (c=='-')?0:(c-'0'); while (c = getchar(),c >= '0'&&c <= '9') { ret = ret * 10 + c - '0'; } return ret*sgn; } int main() { //cout<<-INF<<endl; while(scanf("%d",&n)!=EOF) { for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) a[i][j] = readint(); memset(vis,0,sizeof(vis)); dfs(1,1,1,1,0); cout<<dp[1][1][0]<<endl; } return 0; }