題目鏈接:點我!
三方格取數
描述:
設有N*N的方格圖,我們將其中的某些方格填入正整數,而其他的方格中放入0。
某人從圖得左上角出發,可以向下走,也可以向右走,直到到達右下角。在走過的路上,他取走了方格中的數。(取走後方格中數字變爲0)此人從左上角到右下角共走3次,試找出3條路徑,使得取得的數總和最大。
輸入格式
第一行:N (4<=N<=20)
接下來一個N*N的矩陣,矩陣中每個元素不超過80,不小於0
輸出格式
一行,表示最大的總和。
代碼寫的有點挫,,,
詳細見代碼:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1e5+100;
const int MOD=1e9+7;
typedef long long LL;
typedef unsigned long long llu;
int dp[50][22][22][22];
int A[30][30];
int dx[2]={0,1};
int dy[2]={1,0};
void work(int a,int b,int c,int d,int n)
{
int i,j,k;
int x,y,z;
x=a+2-b;
y=a+2-c;
z=a+2-d;
for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
for(k=0;k<2;k++)
{
int bb=b+dx[i];
int cc=c+dx[j];
int dd=d+dx[k];
int xx=x+dy[i];
int yy=y+dy[j];
int zz=z+dy[k];
if(bb<1||bb>n||cc<1||cc>n||dd<1||dd>n||xx<1||xx>n||yy<1||yy>n||zz<1||zz>n) continue;
int tmp=A[bb][xx];
if(cc!=bb||yy!=xx) tmp+=A[cc][yy];
if((dd==bb&&xx==zz)||(dd==cc&&zz==yy)) ;
else tmp+=A[dd][zz];
if(dp[a+1][bb][cc][dd]<dp[a][b][c][d]+tmp)
dp[a+1][bb][cc][dd]=dp[a][b][c][d]+tmp;
}
}
}
}
int main()
{
int n,m;
scanf("%d",&n);
int i,j,k,v;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
scanf("%d",&A[i][j]);
}
memset(dp,0,sizeof dp);
dp[0][1][1][1]=A[1][1];
for(i=0;i<2*n;i++)
{
for(j=1;j<i+2;j++)
{
if(j>n) break;
for(k=1;k<i+2;k++)
{
if(k>n) break;
for(v=1;v<i+2;v++)
{
if(v>n) break;
work(i,j,k,v,n);
}
}
}
}
printf("%d\n",dp[2*n-2][n][n][n]);
return 0;
}