【Luogu】P1005矩阵取数游戏(高精度+DP)

  题目链接

  yeah终于过辣!

  DP,f[i][j]表示每行还剩i到j这个区间的数没取的时候的值。借这个题我也把高精度的短板弥补了一下,以后高精加高精乘应该是没问题了。

  哇终于不怂高精了……

  放上代码。

  

#include<cstdio>
#include<cctype>
#include<iostream>
#include<cstring>

inline long long read(){
    long long num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-')    f=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        num=num*10+ch-'0';
        ch=getchar();
    }
    return num*f;
}

struct BigInteger{
    int s[100],len;
    BigInteger(){    len=1;    memset(s,0,sizeof(s));    }
    
    bool operator >(BigInteger a){
        if(len!=a.len)    return len>a.len;
        for(int i=len;i;--i){
            if(s[i]!=a.s[i])    return s[i]>a.s[i];
        }
        return 0;
    }
    
    bool operator ==(BigInteger a){
        if(len!=a.len)    return 0;
        for(int i=1;i<=len;++i)
            if(s[i]!=a.s[i])    return 0;
        return 1;
    }
    
    bool operator <(BigInteger a){
        return (!(*this>a)&&!(*this==a));
    }
    
    BigInteger operator =(char* d){
        int size=strlen(d+1);
        (*this).len=size;
        for(int i=size,tot=0;tot<size;--i)    (*this).s[++tot]=d[i]-'0';
        return *this;
    }    
    
    BigInteger operator =(int num){
        char d[100];
        sprintf(d+1,"%d",num);
        *this=d;
        return *this;
    }
    
    inline void out(){
        for(register int i=len;i;--i)    printf("%d",s[i]);
    }
    
    BigInteger operator +(BigInteger a){
        BigInteger ans;
        ans.len=0;
        int size=std::max(len,a.len);
        for(int i=1,g=0;g||i<=size;++i){
            int now=s[i]+a.s[i]+g;
            ans.s[++ans.len]=now%10;
            g=now/10;
        }
        return ans;
    }
    
    BigInteger in(){
        char d[200];
        scanf("%s",d+1);
        *this=d;
        return *this;
    }
    
    BigInteger operator *(BigInteger a){
        BigInteger ans;
        ans.len=0;
        int size=len+a.len;
        for(int i=1;i<=len;++i)
            for(register int j=1;j<=a.len;++j)
                ans.s[i+j-1]+=s[i]*a.s[j];
        for(int i=1;i<size;++i){
            ans.s[i+1]+=ans.s[i]/10;
            ans.s[i]%=10;
        }
        while(size>1&&!ans.s[size])    size--;
        ans.len=size;
        return ans;
    }
    
};

BigInteger Pow(BigInteger a,int b){
    if(b==1)    return a;
    BigInteger ret;
    ret=1;
    while(b){
        if(b&1)    ret=ret*a;
        a=a*a;
        b>>=1;
    }
    return ret;
}

BigInteger f[90][90];
BigInteger d[90][90];
BigInteger ans;
BigInteger two;
int main(){
    two=2;ans=0;
    int n=read(),m=read();
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)    d[i][j]=read();
    for(int T=1;T<=n;++T){
        memset(f,0,sizeof(f));
        for(int len=m;len;--len){
            BigInteger Powval;Powval=Pow(two,m-len);
            for(int i=1;i+len-1<=m;++i){
                int j=i+len-1;
                if(j<m&&f[i][j+1]+Powval*d[T][j+1]>f[i][j])    f[i][j]=f[i][j+1]+Powval*d[T][j+1];
                if(i>1&&f[i-1][j]+Powval*d[T][i-1]>f[i][j])    f[i][j]=f[i-1][j]+Powval*d[T][i-1];
            }
        }
        BigInteger Max;Max=0;
        BigInteger Powval=Pow(two,m);
        for(int i=1;i<=m;++i)
            if(Max<f[i][i]+Powval*d[T][i])    Max=f[i][i]+Powval*d[T][i];
        ans=ans+Max;
    }
    ans.out();
    return 0;
}
原文地址:https://www.cnblogs.com/cellular-automaton/p/7684076.html