loj10152. 「一本通 5.1 练习 3」矩阵取数游戏

思路:
  高精度+区间dp

#include<cstdio>
#include<iostream>
#include<string>
#include<queue>
#include<cstring>
using namespace std;
const int maxn = 110;
struct bignum{
    int num[92];
    bignum(){
        memset(num, 0, sizeof(num));
        num[0] = 1;
    }
    void set(long long x){
        memset(num, 0, sizeof(num));
        while(x){
            num[++num[0]] = x % 10;
            x /= 10;
        }
        if(!num[0])    ++num[0];
    }
    void read(){
        string x;
        cin >> x;
        memset(num, 0, sizeof(num));
        num[0] = x.size();
        for(int i = 1; i <= num[0]; ++i){
            num[i] = x[num[0] - i] - 48;
        }    
    }
    void show(){
        for(int i=num[0]; i>=1; --i)
            cout << num[i];    
    }
    bignum operator + (bignum b){
        bignum c;
        c.num[0] = max(num[0], b.num[0]);
        for(int i=1; i<=c.num[0]; ++i){
            c.num[i] += num[i] + b.num[i];
            if(c.num[i] >= 10){
                c.num[i + 1]++;
                c.num[i] -= 10;
            }
        }
        if(c.num[c.num[0] + 1])    ++c.num[0];
        return c;
    }
    bignum operator * (bignum b){
        bignum c;
        c.set(0);
        c.num[0] = num[0] + b.num[0];
        for(int i=1; i<=num[0]; ++i)
            for(int j=1; j<=b.num[0]; ++j){
                c.num[i + j - 1] += num[i] * b.num[j];
                c.num[i + j] += c.num[i + j - 1] / 10;
                c.num[i + j - 1] %= 10;
            }
        while(c.num[0] > 1 && !c.num[c.num[0]])    --c.num[0];
        return c;
    }
    bool operator < (bignum b) const{
        if(num[0] < b.num[0])    return true;
        if(num[0] > b.num[0])    return false;
        for(int i=num[0]; i>=1; --i){
            if(num[i] > b.num[i])    return false;
            if(num[i] < b.num[i])    return true;
        }
        return false;
    }
};
int n, m;
bignum data[maxn][maxn];
bignum dp[maxn][maxn];
bignum ans;
bignum pow2[maxn];
int main(void) {
    scanf("%d%d", &n, &m);
    pow2[0].set(1);
    bignum two;
    two.set(2);
    for(int i=1; i<=m; ++i)
        pow2[i] = pow2[i-1] * two;
    for(int i=1; i<=n; ++i)
        for(int j=1; j<=m; ++j)
            data[i][j].read();        
    for(int p = 1; p <= n; ++p) {
        for(int i=0; i<=m; ++i)
            for(int j=0; j<=m; ++j)
                dp[i][j].set(0);
        for(int L = 1; L < m; ++L)
            for(int i = 1; i + m - L -1 <= m; ++i){
                int j = i + m - L - 1;
                dp[i][j] = max(dp[i-1][j] + (data[p][i - 1] * pow2[L]), dp[i][j + 1] + (data[p][j + 1] * pow2[L]));
            }
        bignum maxx;
        for(int i=1; i<=m; ++i)
            maxx = max(maxx, dp[i][i] + (data[p][i] * pow2[m]));
        ans = ans + maxx;                                
    }
    ans.show();
}

 

posted @ 2018-08-16 21:00  junk_yao  阅读(179)  评论(0编辑  收藏  举报