[藍橋杯][演算法訓練VIP]方格取數

古城白衣少年i發表於2020-10-05

題目連結:https://www.dotcpp.com/oj/problem1639.html

題目描述

設有N*N的方格圖(N< =10),我們將其中的某些方格中填入正整數,而其他的方格中則放入數字0。
某人從圖的左上角的A  點(1,1)出發,可以向下行走,也可以向右走,直到到達右下角的B點(N,N)。在走過的路上,他可以取走方格中的數(取走後的方格中將變為數字0)。
此人從A點到B  點共走兩次,試找出2條這樣的路徑,使得取得的數之和為最大。

輸入

輸入的第一行為一個整數N(表示N*N的方格圖),接下來的每行有三個整數,前兩個表示位置,第三個數為該位置上所放的數。一行單獨的0表示輸入結束。

輸出

只需輸出一個整數,表示2條路徑上取得的最大的和。 

 

樣例輸入

8
2 3 13
2 6 6
3 5 7
4 4 14
5 2 21
5 6 4
6 3 15
7 2 14
0 0 0

樣例輸出

67

題解一 :記憶化搜尋

可以轉化為兩個人同時由A點走向B點所取得的最大的和。

dp[xi][yi][xj][yj]表示:其中一個人由(xi,yi)到B點,另一個人由(xj,yj)到B點所取得的最大的和。

AC程式碼:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#define cla(a, sum) memset(a, sum, sizeof(a))
#define rap(i, m, n) for(int i=m; i<=n; i++)
#define rep(i, m, n) for(int i=m; i>=n; i--)
#define bug printf("???\n")
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
typedef pair<ll, ll> Pl;
const int Inf = 0x3f3f3f3f;
const double eps = 1e-8;
const int mod=998244353;
const int maxn = 3e4;
const int N=1e5;
template <typename T> void read(T &x){
    x = 0; int f = 1; char ch = getchar();
    while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();}
    while (isdigit(ch)) {x = x * 10 + ch - '0'; ch = getchar();}
    x *= f;
}

int n;
int a[15][15]={0};
int dp[15][15][15][15];

int dfs(int xi,int yi,int xj,int yj){
	if(xi<1||xi>n||yi>n||yi<1||xj<1||xj>n||yj<1||yj>n)
	    return 0;
	if(xi==n&&yi==n&&xj==n&&yj==n)return a[xi][yi];
	if(dp[xi][yi][xj][yj]!=-1)return dp[xi][yi][xj][yj];//剪枝 
	int t=a[xi][yi];
	if(xi!=xj||yi!=yj)t+=a[xj][yj];//兩個人在不同點 
	int x=0;
	//兩個人有四種走法 
	x=max(x,dfs(xi+1,yi,xj+1,yj));
	x=max(x,dfs(xi+1,yi,xj,yj+1));
	x=max(x,dfs(xi,yi+1,xj+1,yj));
	x=max(x,dfs(xi,yi+1,xj,yj+1));
	dp[xi][yi][xj][yj]=x+t;//更新值 
	return dp[xi][yi][xj][yj];
}

int main()
{
	//ios::sync_with_stdio(false),cin.tie(0);
	read(n);
	int x,y,d;
	while(~scanf("%d%d%d",&x,&y,&d)&&(x||y||d)){
		a[x][y]=d;
	}
	cla(dp,-1);
	printf("%d",dfs(1,1,1,1));

	return 0;
}

 

相關文章