• P1005 矩阵取数游戏(动态规划+高精度)


    题目链接:传送门

    题目大意:

    给定长度为m的数列aj,每次从两端取一个数,得到2k * aj的价值(k为当前的次数,从1开始到m),总共有n行这样的数列,求最大价值总和。

    1 ≤ n, m ≤ 80, 0 ≤ aj ≤ 1000;

    思路:

    状态f[i][j]表示取剩下ai,ai+1,…,aj时的最大价值。

    起始状态:

      f[0][m-1] = 0;

    转移方程:

      f[i][j-1] = max(f[i][j-1], f[i][j] + 取掉aj得到的价值);

      f[i+1][j] = max(f[i+1][j], f[i][j] + 取掉ai得到的价值);

    PS:吃灰模板居然出了bug,还因此WA了一发,是时候更新一下高精模板了。

    #include <bits/stdc++.h>
    
    using namespace std;
    const int maxn = 35;
    const int MAX_N = 80 + 5;
    
    
    struct bigInt{
        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;
        }
    
        bigInt() { memset(d, 0, sizeof d); len = 1; }
        bigInt(int num) { *this = num; }
        bigInt(char* num) { *this = num; }
    
        bool operator < (const bigInt& 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 bigInt& b) const{return b < *this;}
        bool operator<=(const bigInt& b) const{return !(b < *this);}
        bool operator>=(const bigInt& b) const{return !(*this < b);}
        bool operator!=(const bigInt& b) const{return b < *this || *this < b;}
        bool operator==(const bigInt& b) const{return !(b < *this) && !(b > *this);}
    
        bigInt 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;
        }
        bigInt operator = (int num) {
            char s[20];
            sprintf(s, "%d", num);
            *this = s;
            return *this;
        }
        bigInt operator + (const bigInt& b) {
            bigInt 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;
        }
        bigInt operator - (const bigInt& b) {
            bigInt 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;
        }//只能正数大减小
        bigInt operator * (const bigInt& b) const {
            bigInt 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;
        }
        bigInt operator / (const bigInt& b) {
            bigInt 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;
        }
        bigInt operator % (const bigInt& b) {
            bigInt 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;
        }
        bigInt operator += (const bigInt& b) {
            *this = *this + b;
            return *this;
        }
    };
    
    istream& operator >> (istream& in, bigInt& x)
    {
        string s;
        in >> s;
        x = s.c_str();
        return in;
    }
    
    ostream& operator << (ostream& out, const bigInt& x)
    {
        out << x.str();
        return out;
    }
    
    int N, M;
    bigInt mat[MAX_N];
    bigInt mul[MAX_N];
    bigInt f[MAX_N][MAX_N];
    
    bigInt dp()
    {
        bigInt cur;
        for (int i = 0; i < M; i++) {
            for (int j = M-1; j > i; j--) {
    //            cout << "f[" << i << "][" << j << "] = " << f[i][j] << ":" << endl;
    //            cout << "f[" << i << "][" << j-1 << "] = " << f[i][j-1] << ' ' << "f[" << i+1 << "][" << j << "] = " << f[i+1][j] << endl;
                f[i][j-1] = max(f[i][j-1], f[i][j] + mul[M-(j-i+1)+1]*mat[j]);
                f[i+1][j] = max(f[i+1][j], f[i][j] + mul[M-(j-i+1)+1]*mat[i]);
    //            cout << "f[" << i << "][" << j-1 << "] = " << f[i][j-1] << ' ' << "f[" << i+1 << "][" << j << "] = " << f[i+1][j] << endl;
            }
        }
        for (int i = 0; i < M; i++) {
            cur = max(cur, f[i][i] + mul[M]*mat[i]);
        }
    //    cout << cur << endl;
        return cur;
    }
    
    int main()
    {
        cin >> N >> M;
        mul[0] = 1;
        for (int i = 1; i < MAX_N; i++)
            mul[i] = mul[i-1] * 2;
        bigInt ans;
        while (N--) {
            for (int i = 0; i < M; i++) {
                cin >> mat[i];
            }
            for (int i = 0; i < M; i++)
                for (int j = i; j < M; j++)
                    f[i][j] = 0;
            ans = ans + dp();
        }
        //模板居然出了bug,怕是在硬盘里吃灰吃多了
        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;
    }
    View Code
  • 相关阅读:
    VS2010 C++环境下DLL和LIB文件目录及名称修改
    什么是lib文件,lib和dll的关系如何
    C++静态库与动态库
    OpenSUSE安装软件
    写给已有编程经验的 Python 初学者的总结
    安装pydiction
    yii webservice 提示:Procedure 'getSent' not present 错误的解决方法(转)
    C# 子线程与主线程通讯方法一
    C#操作Access时Parameters集合的使用方法(转)
    [导航教程] [C#基类库大全]官方产品发布与源码下载---苏飞版
  • 原文地址:https://www.cnblogs.com/Lubixiaosi-Zhaocao/p/9799467.html
Copyright © 2020-2023  润新知