Tsinsen A1127 方格取数

本文探讨了一个复杂的动态规划(DP)问题,即如何通过两人同时从左上角移动到右下角的方式,使得经过每个格子时获得的最大得分最大化。详细解释了从逻辑上构建DP公式的方法,并提供了优化空间复杂度的技巧。代码实现展示了如何通过滚动数组进行空间优化。

http://oj.tsinsen.com/A1127

分析:对我来说挺有难度的dp,唉,还差得远了。

回归正题,这个题的dp从逻辑上讲是这么做的:假设有两个人同时从左上方往右下方走,状态dp[k][x1][y1][x2][y2]定义为走到第k步时两人分别到达(x1,y1)、(x2,y2),这时的最大得数。那么它就可由(x_1,2 + 1,y_1,2)和(x_1,2, y_1,2 + 1)的组合转移而来,并考虑两人是否走到同一方块上(不难证明这种状况必然发生在同一步),加上当前方块的得数。注意到x1+y1=x2+y2=k,考虑题目所给的编号,将初始态定义为第2步,就可写出新的dp公式,此外还可用滚动数组进一步优化空间复杂度,这些都是套路的东西了,具体参见代码。

代码:

#include "bits/stdc++.h"
using namespace std;

int n, Maps[15][15], dp[15][15], r, c, v;

int main() {
    scanf("%d", &n);
    while (scanf("%d%d%d", &r, &c, &v), r)
        Maps[r][c] = v;
    for (int i = 2; i <= n + n; ++i)
        for (int u = min(i, n); u > 0; --u)
            for (int v = min(i, n); v > 0; --v) {
                dp[u][v] = max(dp[u][v], dp[u - 1][v - 1]);
                dp[u][v] = max(dp[u][v], dp[u - 1][v]);
                dp[u][v] = max(dp[u][v], dp[u][v - 1]);
                dp[u][v] += Maps[u][i - u];
                if (u != v) dp[u][v] += Maps[v][i - v];
            }
    printf("%d\n", dp[n][n]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值