【Acwing1027】方格取数(动态规划)题解

题目描述

思路分析

错误思路:

贪心法,先走一次求出最大值,把走过的路上面的数值清零,然后用同样的方法再走一遍求最大值,然后让这两个最大值相加就是最后的结果。

很多人在看到这个题目的时候会有上面的思路,但实践告诉我们,有些数据用上述思路答案是错误的,这是为什么呢?

原因很简单:假设第一次走的时候,有多条路径s1,s2,......可以得到最大值,我们并不知道要选择哪一条,也就是说我们并不知道要把哪一条路上面的数清零,因为不同的选择会对第二次走的结果产生影响!!!

所以要使用其它思路,此处采用动态规划解决

起初,我们很容易想到用四维数组表示状态f[i1][j1][i2][j2]

但其实没有必要,因为我们只需要两条路"同时走"就可以了,也就是说我们可以设置一个维度代表(x,y方向上已经走的路径的和),这个表示为k,那么状态就可以降成三维:f[k][i1][i2]

下面对集合进行划分:

对于f[k][i1][i2],包含四部分:

第一部分是第一条路从上边走过来,第二条路是从上面走过来 f[k-1][i1-1][i2-1]+t

第二部分是第一条路从右边走过来,第二条路是从上面走过来 f[k-1][i1][i2-1]+t

第三部分是第一条路从上边走过来,第二条路是从右面走过来 f[k-1][i1-1][i2]+t

第四部分是第一条路从右边走过来,第二条路是从右面走过来 f[k-1][i1][i2]+t

那么这个t,怎么求,就要看i1和i2是否相同了,因为如果相同的话,再走到这里值已经清空了:

i1==i2 t=w[i1][k-i1]

i1!=i2 t=w[i1][k-i1]+w[i2][k-i2]

最后答案即为:f[n+n][n][n]

cpp 复制代码
#include<iostream>
using namespace std;
const int N=15;
int f[N*2][N][N];
int w[N][N];
int n;
int main()
{
    scanf("%d",&n);
    int a,b,c;
    while(cin>>a>>b>>c,a||b||c)w[a][b]=c;
    for(int k=2;k<=n*2;k++)
    {
        for(int i1=1;i1<=n;i1++)
        {
            for(int i2=1;i2<=n;i2++)
            {
                int j1=k-i1,j2=k-i2;
                if(j1>=1&&j1<=n&&j2>=1&&j2<=n)
                {
                    int t=w[i1][j1];
                    if(i1!=i2)t+=w[i2][j2];
                    int &x=f[k][i1][i2];
                    x=max(x,f[k-1][i1-1][i2-1]+t);
                    x=max(x,f[k-1][i1-1][i2]+t);
                    x=max(x,f[k-1][i1][i2-1]+t);
                    x=max(x,f[k-1][i1][i2]+t);
                }
            }
        }
    }
    cout<<f[2*n][n][n];
    return 0;
}
相关推荐
girl-07265 分钟前
2025.12.28代码分析总结
算法
NAGNIP3 小时前
GPT-5.1 发布:更聪明,也更有温度的 AI
人工智能·算法
NAGNIP3 小时前
激活函数有什么用?有哪些常用的激活函数?
人工智能·算法
宇宙超级无敌暴龙战士3 小时前
旮旯c语言三个任务
c++·c
元亓亓亓4 小时前
LeetCode热题100--416. 分割等和子集--中等
算法·leetcode·职场和发展
BanyeBirth4 小时前
C++差分数组(二维)
开发语言·c++·算法
Fcy6484 小时前
C++ map和multimap的使用
开发语言·c++·stl
CC.GG4 小时前
【C++】STL容器----unordered_map和unordered_set的使用
java·数据库·c++
lengjingzju5 小时前
基于IMake的 GCC 编译与链接选项深度解析:构建高效、安全、可调试的现代软件
c++·安全·性能优化·软件构建·开源软件
xu_yule5 小时前
算法基础(数论)—算法基本定理
c++·算法·算数基本定理