LGOJ P1018 乘积最大

LGOJ P1018 乘积最大

首先不难想到状态转移方程:

\[f[i][j]=max\{ f[s][j-1] \times calc(s+1,i) \} , s \in (0,i) , i\in [1,n], j\in [1,K] \]

\(f[i][j]\)表示在\(i\)位置时已经用了\(j\)个乘号,表示当前的最大值。

\(calc(L,R)\)表示从\(L\)位置到\(R\)位置表示的数。

数的全部类型都是bigint。不高精度会炸锅。

考虑初始化。任何不放乘号的情况:\(f[i][0]=calc(1,i), i \in [1,n]\)

其余情况\(f[i][j]=0\)

code:

#include <iostream>
#include <vector>
#include <list>
#include <cstring>
#include <queue>
#include <cstring>
#include <cctype>
#define ll long long
using namespace std;
struct bigint
{
    vector<int> s;
    void read()
    {
        s.clear();
        string a;
        cin >> a;
        for (int i = a.size() - 1; i >= 0; i--)
            s.push_back(a[i] - '0');
    }
    void pr()
    {
        bool flag = 1;
        //cout<<s.size()<<endl;
        if (s.size() == 1 && s[0] == 0)
        {
            putchar('0');
            return;
        }
        for (int i = s.size() - 1; i >= 0; i--)
        {
            if (s[i] == 0 && flag)
                continue;
            else
                flag = 0;
            putchar(s[i] + '0');
        }
    }
    bool operator<(const bigint &a) const
    {
        if (s.size() != a.s.size())
            return s.size() < a.s.size();
        for (int i = s.size() - 1; i >= 0; i--)
            if (s[i] != a.s[i])
                return s[i] < a.s[i];
    }
    bigint operator+(const bigint &a) const
    {
        bigint c;
        c.s.clear();
        int p = 0, size = max(s.size(), a.s.size());
        c.s.assign(size, 0);
        for (int i = 0; i < size; i++)
        {
            c.s[i] += p;
            if (i < s.size())
                c.s[i] += s[i];
            if (i < a.s.size())
                c.s[i] += a.s[i];
            p = c.s[i] / 10;
            c.s[i] %= 10;
        }
        while (p)
        {
            c.s.push_back(p % 10);
            p /= 10;
        }
        return c;
    }
    bigint operator*(const bigint a) const
    {
        bigint c;
        c.s.assign(s.size() + a.s.size(), 0);
        for (int i = 0; i < s.size(); i++)
            for (int j = 0; j < a.s.size(); j++)
                c.s[j + i] += a.s[j] * s[i];
        int p = 0;
        for (int i = 0; i < c.s.size(); i++)
        {
            c.s[i] += p;
            p = c.s[i] / 10;
            c.s[i] %= 10;
        }
        while (p)
        {
            c.s.push_back(p % 10);
            p /= 10;
        }
        return c;
    }
    bool empty()
    {
        return s.empty();
    }
    bigint operator=(int num)
    {
        s.clear();
        while (num)
        {
            s.push_back(num % 10);
            num /= 10;
        }
        return *this;
    }
};

int n, K, a[100];
bigint f[100][100];
bigint ans, aa;

bigint max(bigint &a, bigint &b)
{
    if (a < b)
        return b;
    else
        return a;
}

bigint calc(int L, int R)
{
    bigint r;
    for (int i = R; i >= L; i--)
        r.s.push_back(a[i]);
    return r;
}

int main()
{
    cin >> n >> K;
    for (int i = 1; i <= n; i++)
        scanf("%1d", &a[i]);
    bigint d;
    for (int i = 1; i <= n; i++)
    {
        f[i][0] = calc(1, i);
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= K; j++)
        {
            for (int s = 1; s < i; s++)
            {
                f[i][j] = max(f[i][j], f[s][j - 1] * calc(s + 1, i));
            }
        }
    }
    f[n][K].pr();
    return 0;
}
posted @ 2019-11-14 11:01  miyasaka  阅读(109)  评论(0)    收藏  举报