美文网首页动态规划
洛谷 P1043 数字游戏 题解

洛谷 P1043 数字游戏 题解

作者: 帅气的小屁孩_8d50 | 来源:发表于2018-10-31 22:25 被阅读33次

思路

我们设dp(i)(j)(k)为在区间[i, j]内的答案,这个答案从[i,j]m个小区间转移而来。那么转移方程就是
dp(i)(j)(k) = 1 \ (k == 1) \\ dp(i)(j)(k) = max \{ dp(i)(p)(k - 1) \times [sum(j) - sum(p)] \, | \, (i + k - 2 \le p < j)\}

要注意的地方

  • 区间类型有关动态规划的问题一般可以用区间DP合并来解决
  • 注意枚举的中间点的p的范围,只有大于i + k - 2这样dp(i)(p)(k - 1)才能保证从m-1个区间转移而来

代码

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 55 * 2;
const int M = 15;
const int MOD = 10;
const int INF = 0x3f3f3f3f;

int n, m, arr[N], sum[N];
int dp_min[N][N][M];
int dp_max[N][N][M];

inline int Min(int x, int y) {
    return x <= y ? x : y;
}

inline int Max(int x, int y) {
    return x >= y ? x : y;
}

int read() {
    int s = 0, w = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-') w = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        s = s * 10 + ch - '0';
        ch = getchar();
    }
    return s * w;
}

void write(int x) {
    if (x < 0) putchar('-'), x = -x;
    if (x > 9) write(x / 10);
    putchar(x % 10 + '0');
}

int main(int argc, char const *argv[]) {
    n = read(), m = read();
    for (register int i = 1; i <= n; ++i) 
        arr[i] = read(), sum[i] = sum[i - 1] + arr[i];
    for (register int i = n + 1; i <= 2 * n; ++i) 
        arr[i] = arr[i - n], sum[i] = sum[i - 1] + arr[i];
    for (register int len = 1; len <= 2 * n; ++len) {
        for (register int l = 1; l + len - 1 <= 2 * n; ++l) {
            int r = l + len - 1;
            for (register int num = 1; num <= m; ++num) {
                if (num == 1) {
                    dp_min[l][r][num] = ((sum[r] - sum[l - 1]) % MOD + MOD) % MOD;
                    dp_max[l][r][num] = ((sum[r] - sum[l - 1]) % MOD + MOD) % MOD;
                } else {
                    dp_min[l][r][num] = INF;
                    dp_max[l][r][num] = -INF;
                    for (register int k = l + num - 2; k < r; ++k) {
                        dp_min[l][r][num] = Min(dp_min[l][r][num], 
                                                dp_min[l][k][num - 1] * (((sum[r] - sum[k]) % MOD + MOD) % MOD));
                        dp_max[l][r][num] = Max(dp_max[l][r][num], 
                                                dp_max[l][k][num - 1] * (((sum[r] - sum[k]) % MOD + MOD) % MOD));
                    }
                }
            }
        }
    }
    int ans_min = INF;
    int ans_max = -INF;
    for (register int l = 1; l + n - 1 <= 2 * n; ++l) {
        int r = l + n - 1;
        ans_min = Min(ans_min, dp_min[l][r][m]);
        ans_max = Max(ans_max, dp_max[l][r][m]);
    }
    write(ans_min), putchar('\n');
    write(ans_max), putchar('\n');
    return 0;
}

相关文章

  • 洛谷 P1043 数字游戏 题解

    思路 我们设为在区间内的答案,这个答案从内个小区间转移而来。那么转移方程就是 要注意的地方 区间类型有关动态规划的...

  • 洛谷P1025题解

    题目链接:洛谷P1025 题目描述 将整数分成份,且每份不能为空,任意两个方案不相同(不考虑顺序)。 例如:,下面...

  • 洛谷P1002题解

    少儿编程咨询、算法咨询请加微信307591841或QQ群581357582诺依曼算法公众号.jpg

  • 优质题解:数字游戏

    原题链接:[蓝桥杯][历届试题]数字游戏 解题思路:【1】.首先是明确只能计算主角的数,如果计算了别人的数,那么时...

  • [题解]1016-数字游戏

    题目(状态DP) 丁丁最近沉迷于一个数字游戏之中。这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则...

  • 2018 CCF NOIP Junior 题解

    2018 CCF NOIP Junior 题解 标题统计 洛谷自测 P5015 牛客网自测 277A 给定一个字符...

  • 洛谷P1141 01迷宫 题解

    一条搜索水题,竟然交了10次才a...还是太菜了,怒献一篇题解,思路是记忆化dfs+剪枝。先看一下题目:(截图拼接...

  • 洛谷 P1049 装箱问题 题解

    思路 这个题目其实只要把 0 1背包中的每个物品的价值改成每个物品的重量就可以了。 总结 我们在进行动态规划的时候...

  • 洛谷题解P1036 选数

    一、题目 https://www.luogu.org/problemnew/show/P1036 二、代码 少儿编...

  • 洛谷题解P1010 幂次方

    一、题目 https://www.luogu.org/problemnew/show/P1010 二、代码 少儿编...

网友评论

    本文标题:洛谷 P1043 数字游戏 题解

    本文链接:https://www.haomeiwen.com/subject/zzwgtqtx.html