方格取数

方格取数
难度级别:B; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B
试题描述
设有N×N的方格图,我们在其中的某些方格中填入正整数,而其它的方格中则放入数字0。如下图所示:



某人从图中的左上角的A出发,可以向下行走,也可以向右行走,直到达右下角的B点。在走过的路上,他可以取走方格中的数(取走后的方格中将变为数字0)。

此人从A点到B点共走了两次,试找出两条这样的路径,使得取得的数字和为最大。

输入
输入第一行为一个整数N(N≤10),表示N×N的方格图。
接下来的每行有三个整数,第一个为行号数,第二个为列号数,第三个为在该行、该列上所放的数。一行0 0 0表示结束。
输出
输出包含一个整数,表示两条路径上取得的最大的和。 
输入示例
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

 

本蒟蒻第一次写博客,发一些水题。大佬勿喷。欢迎大佬们指出不足。

思路:这道题是一道裸的动规,不能分两次走,要一次拿完才可以拿到最大,所以一种状态可能有四组状态转移过来(上上,上左,左上,左左),要选取其中最大的一种情况,当两人同时走到一点的时候还要判重。有四种情况所以要开一个四维数组和一个四重循环。然后是参考代码

#include<bits/stdc++.h>
using namespace std;
int dp[15][15][15][15],a[15][15];
int x,y,z,n;
int main()
{
    scanf("%d%d%d%d",&n,&x,&y,&z);
    while(x!=0&&y!=0&&z!=0)//不等于零就一直输入 
    {
        a[x][y]=z;//坐标为x,y的点数是z 
        scanf("%d%d%d",&x,&y,&z);
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            for(int k=1;k<=n;k++)
            {
                for(int f=1;f<=n;f++)
                {
                    dp[i][j][k][f]=max(max(dp[i-1][j][k-1][f],dp[i-1][j][k][f-1]),max(dp[i][j-1][k][f-1],dp[i][j-1][k-1][f]))+a[i][j]+a[k][f];//动态转移方程,判断四种情况哪种最大 
                    if(i==k&&j==f) dp[i][j][k][f]-=a[i][j];//判重 
                }
            }
        }
    }
    printf("%d",dp[n][n][n][n]);//输出
    return 0//完美解决 
}

题解结束,希望这道题对你有所帮助。有不懂的地方欢迎交流,也欢迎大佬们指出错误。

原文地址:https://www.cnblogs.com/jiuduSHENBENG/p/9489232.html