2019年7月训练(叁)

luogu 1005+高精度模板

dp方程:

 dp[i][j-1]=max(dp[i][j-1],dp[i][j]+Mul[m-(j-i+1)+1]*mi[j]);
 dp[i+1][j]=max(dp[i+1][j],dp[i][j]+Mul[m-(j-i+1)+1]*mi[i]);

#include <bits/stdc++.h>
const int maxn = 55;
const int MAX_N = 85;
using namespace std;

struct Int{
    int len, d[maxn];

    void clean() { while(len > 1 && !d[len-1]) len--; }
    string str() const {
        string s;
        for (int i = 0; i < len; i++) s += d[len-1-i] + '0';
        return s;
    }

    Int() { memset(d, 0, sizeof d); len = 1; }
    Int(int num) { *this = num; }
    Int(char* num) { *this = num; }

    bool operator < (const Int& b) const {
        if(len != b.len)
            return len < b.len;
        for (int i = len-1; i >= 0; i--)
            if (d[i] != b.d[i])
                return d[i] < b.d[i];
        return false;
    }
    bool operator >(const Int& b) const{return b < *this;}
    bool operator<=(const Int& b) const{return !(b < *this);}
    bool operator>=(const Int& b) const{return !(*this < b);}
    bool operator!=(const Int& b) const{return b < *this || *this < b;}
    bool operator==(const Int& b) const{return !(b < *this) && !(b > *this);}

    Int operator = (const char* num) {
        memset(d, 0, sizeof d);
        len = strlen(num);
        for (int i = 0; i < len; i++)
            d[i] = num[len-1-i] - '0';
        clean();
        return *this;
    }
    Int operator = (int num) {
        char s[20];
        sprintf(s, "%d", num);
        *this = s;
        return *this;
    }
    Int operator + (const Int& b) {
        Int c = *this;
        for (int i = 0; i < b.len; i++) {
            c.d[i] += b.d[i];
            c.d[i+1] += c.d[i]/10;
            c.d[i] %= 10;
        }
        c.len = max(len, b.len)+1;
        c.clean();
        return c;
    }
    Int operator - (const Int& b) {
        Int c = *this;
        int i;
        for (i = 0; i < b.len; i++) {
            c.d[i] -= b.d[i];
            if (c.d[i] < 0) c.d[i] += 10, c.d[i+1]--;
        }
        while (c.d[i] < 0) c.d[i++] += 10, c.d[i]--;
        c.clean();
        return c;
    }//只能正数大减小
    Int operator * (const Int& b) const {
        Int c;
        for (int i = 0; i < len; i++)
            for (int j = 0; j < b.len; j++)
                c.d[i+j] += d[i] * b.d[j];
        for (int i = 0; i < len+b.len || !c.d[i]; c.len = ++i) {
            c.d[i+1] += c.d[i] / 10;
            c.d[i] %= 10;
        }
        c.clean();
        return c;
    }
    Int operator / (const Int& b) {
        Int c = *this, res = 0;
        for (int i = 0; i < len; i++) {
            res = res*10 + c.d[len-1-i];
            int j;
            for (j = 0; j < 10; j++)
                if(res < b*(j+1))
                    break;
            c.d[len-1-i] = j;
            res = res - b*j;
        }
        c.clean();
        return c;
    }
    Int operator % (const Int& b) {
        Int res = 0;
        for (int i = 0; i < len; i++) {
            res = res*10 + d[len-1-i];
            int j;
            for (j = 0; j < 10; j++)
                if(res < b*(j+1))
                    break;
            res = res - b*j;
        }
        return res;
    }
    Int operator += (const Int& b) {
        *this = *this + b;
        return *this;
    }
};

istream& operator >> (istream& in, Int& x)
{
    string s;
    in >> s;
    x = s.c_str();
    return in;
}

ostream& operator << (ostream& out, const Int& x)
{
    out << x.str();
    return out;
}

int n,m;
Int Mul[85],dp[85][85],mi[85];

Int f()
{
    Int qaq;
    for(int i=0;i<m;i++)
    {
        for(int j=m-1;j>i;j--)
        {
            dp[i][j-1]=max(dp[i][j-1],dp[i][j]+Mul[m-(j-i+1)+1]*mi[j]);
            dp[i+1][j]=max(dp[i+1][j],dp[i][j]+Mul[m-(j-i+1)+1]*mi[i]);
        }
    }
    for(int i=0;i<m;i++)
    {
        qaq=max(qaq,dp[i][i]+Mul[m]*mi[i]);
    }
    return qaq;
}

int main()
{
    scanf("%d%d",&n,&m);
    Mul[0]=1;
    for(int i=1;i<85;i++)
    {
        Mul[i]=Mul[i-1]*2;
    }
    Int ans;
    while(n--)
    {
        for(int i=0;i<m;i++)
        {
            cin>>mi[i];
        }
        for(int i=0;i<m;i++)
        {
            for(int j=i;j<m;j++)
            {
                dp[i][j]=0;
            }
        }
        ans+=f();
    }
    while(ans.d[ans.len-1]>10)
    {
        ans.d[ans.len]=ans.d[ans.len-1]/10;
        ans.d[ans.len-1]%=10;
        ans.len++;
    }
    cout<<ans<<endl;
    return 0;
 } 

 2019-07-2915:27:30


待补完:重载运算符

2019-07-29

原文地址:https://www.cnblogs.com/plzplz/p/11264120.html