[luogu] P1005 矩阵取数游戏

题目详情
题目分析:
这一题数据范围太大,要用高精加,但我使用的是比较简单的__int128

  • __int128需要用快读才能读入,输出也需要自己写函数。
  • 因为每一行的结果都独立,所以我们可以一行一行的做动规。
  • 状态转移方程是:
    m a t r i x [ i ] [ j ] = m a x ( m a t r i x [ i ] [ j ] , m a t r i x [ i 1 ] [ j ] + t e m p [ i 1 ] b a s e [ m j + i 1 ] ) ; matrix[i][j] = max(matrix[i][j], matrix[i - 1][j] + temp[i - 1] * base[m - j + i - 1]);
  • 状态转移方程表示区间i~j内的最大值,上次拿掉的是位置i - 1上的数字其值为temp[i - 1],是第m - j + i - 1次拿。转移到现在这个区间i~j的状态。
#include <cmath>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
using namespace std;
void print(__int128 x){
    if (x > 9) print(x / 10);
    putchar(x % 10 + 48);
}
inline void read(__int128 &res)
{
    char c;
    res = 0;
    while (!(isdigit(c = getchar())));
    while (isdigit(c)) res = res * 10 + c - '0', c = getchar();
}
__int128 matrix[88][88], ans, temp[88], base[88], n, m;
int main()
{
    read(n), read(m);
    base[0] = 1;
    for (int i = 1; i <= m; i++) base[i] = base[i - 1] * 2;
    while (n--)
    {
        __int128 TempAns = 0;
        memset(matrix, 0, sizeof(matrix));
        for (int i = 1; i <= m; i++)
            read(temp[i]);
        for (int i = 1; i <= m; i++)
            for (int j = m; j >= i; j--)
            {
                matrix[i][j] = max(matrix[i][j], matrix[i - 1][j] + temp[i - 1] * base[m - j + i - 1]);
                matrix[i][j] = max(matrix[i][j], matrix[i][j + 1] + temp[j + 1] * base[m - j + i - 1]);
            }
        for (int i = 1; i <= m; i++)
            TempAns = max(TempAns, matrix[i][i] + base[m] * temp[i]);
        ans += TempAns;
        }
    print(ans);
}
发布了23 篇原创文章 · 获赞 0 · 访问量 954

猜你喜欢

转载自blog.csdn.net/weixin_45646006/article/details/105603145