故事的起源不加贅述,那23個路口。 單刀直入,我直接說題的意思。 蚊子和瘋子在作一件事,就是他們要在茫茫的大街上找一個出發點,而後從出發點開始,通過上下左右23次拐彎,到達一個他們也不知道的地方。 老城的街道排列的十分有規律,因而瘋子和蚊子把老城的街道排布畫在了一張地圖上。地圖上每個點表明一個地方,而這個地方有必定的憧憬值,瘋子但願能夠帶蚊子走過的二十三個路口的憧憬值總和是全部方案中最大的。 如今咱們讀入一個矩陣,若是此點爲0,則這個點爲起點,若是此點爲-1,則這個點爲障礙點,不然這個數表明憧憬值。注意起點和障礙點是沒有憧憬值的,起點只有開始的時候能夠達到,不能夠再回來。而障礙點根本就不能夠走過。這樣一來,請你選擇合適的路線,使走完23個路口後獲得最大的憧憬值,有憧憬值的點能夠重複進出,每次能夠選擇四個方向,上下左右。起點爲第0個路口 輸入格式: 第1行兩個整數 n,m (茫茫大街的長和寬) 第2行到第m+1行,每行n個整數 Aij(第I行第j個地點的憧憬值) 輸出格式 一個整數sum (能夠獲得的最大憧憬值) INPUT 4 4 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 OUTPUT 23 對於30%的數據,n,m<=50 對於所有數據 n,m<=300 0<n,m<300,每一個點的憧憬值能夠用longint表示。
DP題。由於每一個點均可以重複進入,因此咱們能夠獲得方程ios
F[k,I,j]:=max(f[k-1,i-1,j],f[k-1,I+1,j],f[k-1,I,j-1],f[k-1,I,j+1])+a[I,j];git
由於有障礙點和出發點,因此咱們要作出必定的預處理。ide
注意邊界的判斷spa
Code:code
(代碼源自cyh大佬blog
#include<cstdio> #include<algorithm> #include<cctype> #include<cstring> #include<iostream> #define maxn 307 #define int long long using namespace std; const int inf=0x3f3f3f3f3f3f3f3f; int f[maxn][maxn][27],n,m,a[maxn][maxn],ans=-inf; int qread() { char c=getchar();int num=0,f=1; for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) num=num*10+c-'0'; return num*f; } signed main() { freopen("corner.in","r",stdin); freopen("corner.out","w",stdout); memset(f,-0x3f,sizeof(f)); m=qread(),n=qread(); for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) { a[i][j]=qread(); if(!a[i][j]) f[i][j][0]=0; } } for(int i=1;i<=23;++i) { for(int x=1;x<=n;++x) { for(int y=1;y<=m;++y) { if(!a[x][y]||a[x][y]==-1) continue; if(x>1&&~a[x-1][y]) f[x][y][i]=max(f[x][y][i],f[x-1][y][i-1]+a[x][y]); if(x<n&&~a[x+1][y]) f[x][y][i]=max(f[x][y][i],f[x+1][y][i-1]+a[x][y]); if(y>1&&~a[x][y-1]) f[x][y][i]=max(f[x][y][i],f[x][y-1][i-1]+a[x][y]); if(y<m&&~a[x][y+1]) f[x][y][i]=max(f[x][y][i],f[x][y+1][i-1]+a[x][y]); } } } for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) ans=max(ans,f[i][j][23]); cout<<ans<<'\n'; fclose(stdin),fclose(stdout); return 0; } /* 4 4 2 3 1 0 4 3 2 -1 8 2 -1 -1 1 3 -1 1 127 */