P1004 方格取数(DP 状态设计)

两次路径并不容易贪心,看到数据范围应当采取动态规划解决。
之所以我们不能跑两次最优解解决这个问题,是因为存在重合节点,这样的节点只能取一次。
当我们决定存储两次移动的终点作为状态后,关键就是对于重合节点的处理。
可以限定总步数和两次终点的横坐标,纵坐标可以求出,判断横坐标是否相等即可判断重合。

#include<bits/stdc++.h>
using namespace std;
const int N=15;
int n,mp[N][N],dp[N][N],pre[N][N];
int main(){
    scanf("%d",&n);
    for(int a,b,c;;){
        scanf("%d%d%d",&a,&b,&c);
        if(a==0) break;
        mp[a][b]=c;
    }
    pre[1][1]=mp[1][1];
    for(int step=3;step<=n+n;step++){
        //注意边界处理
        for(int a=max(1,step-n),b;(b=step-a)>0&&a<=n;a++)
            for(int c=max(1,step-n),d;(d=step-c)>0&&c<=n;c++){
                dp[a][c]=max(max(pre[a][c],pre[a-1][c]),max(pre[a][c-1],pre[a-1][c-1]));
                dp[a][c]+=mp[a][b]+mp[c][d]-(a==c)*mp[a][b];
            }
        for(int a=1;a<=n;a++)
            for(int c=1;c<=n;c++)
                pre[a][c]=dp[a][c],dp[a][c]=0;
    }
    printf("%d\n",pre[n][n]);
    return 0;
}

posted @ 2026-02-03 21:31  2025ing  阅读(0)  评论(0)    收藏  举报