洛谷OJ: P1005 矩阵取数游戏

今天因为高数模拟考没怎么做题,就睡前做了这么一题,舍友也开始一起在洛谷刷题了,很开心,但是高数只考了63,很不开心,心情复杂。

思路:每一行都是独立的选择,不要因为有多行而被带到错误的思考方向,所以我们开始分析独立的一行数据,那么只有两种选择,1.选择最开头的数字 2.选择最末尾的数字, 而每次增加的分数都是2^i*选择的数字,那么我们稍加思考就可以得到状态转移方程啦。

首先,我们定义dp[i][j]为区间(i,j)可以得到的最大分数那么我们可以得出状态转移方程

dp[i][j] = max{dp[i+1][j]*2+num[i]*2, dp[i][j-1]*2+num[j]*2} (i+1 <= j)

但是通过分析,这题的m给定的数据范围上限是80,也就是说最好的情况也有2^80的大小了!这就超出了longlong的数据大小,所以我们选择用大数类来解决这一题。

因为我的大数类模板有300行左右,太长了,就不放出来了。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;

const int maxn = 80+5;
int n, m;
BigNum dp[maxn][maxn], num[maxn], ans;

int main() {
    ios::sync_with_stdio(false);
    cin >> n >> m;
    while(n--) {
        for(int i = 1; i <= m; i++) {
            cin >> num[i];
            dp[i][i] = 2*num[i];
        }
        for(int i = m-1; i >= 1; i--) {
            for(int j = i+1; j <= m; j++) {
                BigNum a = 2 * dp[i+1][j] + 2*num[i];
                BigNum b = 2*dp[i][j-1] + 2 * num[j];
                dp[i][j] = a > b ? a : b;
            }
        }
        ans = ans + dp[1][m];
    }
    cout << ans << endl;
    return 0;
}

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Elvis_code_t/article/details/79955591
个人分类: DP学习 洛谷OJ
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭