P1004 [NOIP2000 提高组] 方格取数

题目描述

设有$N\times N$的方格图 $(n\leqslant 9)$,我们将其中的某些方格中填入正整数,而其他的方格中则放入数字 $0$。如下图所示(见样例):

A
  0  0  0  0  0  0  0  0
  0  0 13  0  0  6  0  0
  0  0  0  0  7  0  0  0
  0  0  0 14  0  0  0  0
  0  21  0  0  0  4  0  0
  0  0 15  0  0  0  0  0
  0 14  0  0  0  0  0  0
  0  0  0  0  0  0  0  0
                           B

某人从图的左上角的$A$点出发,可以向下行走,也可以向右走,直到到达右下角的 $B$ 点。在走过的路上,他可以取走方格中的数(取走后的方格中将变为数字 $0$)。
此人从 $A$ 点到 $B$ 点共走两次,试找出 $2$ 条这样的路径,使得取得的数之和为最大。

输入格式

输入的第一行为一个整数 $N$(表示 $N\times 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

分析

四维$Dp$,前两维表示第一条路取得的最大值,后两维表示第二条路的最大值,注意判重并删除或如果不重就相加。状态转移方程$$Temp_1=max\{Dp_{i-1,j,p-1,q},Dp_{i-1,j,p,q-1}\}\\Temp_2=max\{Dp_{i,j-1,p-1,q},Dp_{i,j-1,p,q-1}\}\\Dp_{i,j,p,q}=max\{Temp_1,Temp_2\}+G_{i,j}$$

代码

#include <bits/stdc++.h>

#define Enter puts("")
#define Space putchar(' ')

using namespace std;

typedef long long ll;
typedef double Db;

inline ll Read()
{
    ll Ans = 0;
    char Ch = getchar() , Las = ' ';
    while(!isdigit(Ch))
    {
        Las = Ch;
        Ch = getchar();
    }
    while(isdigit(Ch))
    {
        Ans = (Ans << 3) + (Ans << 1) + Ch - '0';
        Ch = getchar();
    }
    if(Las == '-')
        Ans = -Ans;
    return Ans;
}

inline void Write(ll x)
{
    if(x < 0)
    {
        x = -x;
        putchar('-');
    }
    if(x >= 10)
        Write(x / 10);
    putchar(x % 10 + '0');
}


int Dp[101][101][11][11];
int G[101][101];
int x , y , n;
int Value;

int main()
{
    scanf("%d%d%d%d" , &n ,&x , &y , &Value);
    while(x && y && Value)
        G[x][y] = Value , scanf("%d%d" , &x , &y , &Value);
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)    
            for(int p = 1; p <= n; p++)
                for(int q = 1; q <= n; q++)
                {
                     int Temp1 = max(Dp[i - 1][j][p - 1][q] , Dp[i - 1][j][p][q - 1]);
                     int Temp2 = max(Dp[i][j - 1][p - 1][q] , Dp[i][j - 1][p][q - 1]);
                     Dp[i][j][p][q] = max(Temp1 , Temp2) + G[i][j];
                        if(i != p && q != j)
                            Dp[i][j][p][q] += G[p][q];
                }
    printf("%d" , Dp[n][n][n][n]);
    return 0;
}

 

上一篇:PHP-为什么这一行代码不需要转义引号


下一篇:mui使用video.js播放视频安卓手机无法全屏问题