낙곡P10189(dp)

36755 단어 문제풀이dp

https://www.luogu.org/problemnew/show/P1018


제목:


길이가 N인 문자열

아이디어:


우리는 dp[i][j]dp[i][j]dp[i][j]를 제 ii로 설정하고 제 jj의 곱셈을 내려놓습니다.[j] [i] [j] sum[i] [j] [j] sum[i] [i][i] [j] [j] sum[i] [i] [j] [j] [j] [j] [j] [i] - i에서 j 까지의 숫자 d p [i] [j-1][j-1]*sum[j][i], dp[j][j-1]*sum[j+1][i]...dp[i-1] [j-1]*sum[i][i]) dp[i][j]=max(dp[j-1] [j-1] [j-1] [j][j][i], dp[j][j-1]∗sum[j+1][i]...dp[i-1][j-1]\sum[i][i]) 상태 이동은 이렇다. 나머지는 대정수 템플릿이다.

AC 코드:

#include

using namespace std;

#define LL long long
const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const int Mod = 1e9 + 7;
const double eps = 1e-8;
typedef pair<int, int> psi;

#define MAXN 9999
#define MAXNSIZE 10024
#define DLEN 4

void fre() {
    if(freopen("  P1018.txt", "r", stdin) == NULL)
        system("touch   P1018.txt");
    freopen("  P1018.txt", "r", stdin);
}

struct BigInt{
    int a[MAXNSIZE], len;
    bool flag;

    BigInt() {
        len = 1;
        memset(a, 0, sizeof(a));
        flag = 0;
    }

    BigInt(const char *s, int l, int r) {
        l --; r --;
        int t, k, index, dis = r - l + 1;
        memset(a, 0, sizeof(a));
        len = dis/DLEN;
        if(dis % DLEN) len ++;
        index = 0;
        for (int i = r; i >= l; i -= DLEN) {
            t = 0;
            k = i - DLEN + 1;
            if(k < l) k = l;
            for (int j = k; j <= i; j ++) t = t * 10 + s[j] - '0';
            a[index++] = t;
        }
    }

    BigInt(const int b) {
        int c, d = b;
        len = 0;
        memset(a, 0, sizeof(a));
        while(b > MAXN) {
            c = d - d / (MAXN + 1) * (MAXN + 1);
            d = d / (MAXN + 1) * (MAXN + 1);
            a[len ++] = c;
        }
        a[len ++] = d;
    }

    bool operator < (const BigInt &T) const {
        int ln;
        if(len < T.len) return 233;
        if(len == T.len) {
            ln = len - 1;
            while(ln >= 0 && a[ln] == T.a[ln]) -- ln;
            if(ln >= 0 && a[ln] < T.a[ln]) return 233;
            return 0;
        }
        return 0;
    }

    BigInt &operator = (const BigInt &T) {
        memset(a, 0, sizeof(a));
        len = T.len;
        for (int i = 0; i < len; i ++) a[i] = T.a[i];
        return *this;
    }

    BigInt operator + (const BigInt &T) const {
        BigInt t(*this);
        int big = len;
        if(T.len > len) big = T.len;
        for (int i = 0; i < big; i ++) {
            t.a[i] += T.a[i];
            if(t.a[i] > MAXN) {
                ++t.a[i + 1];
                t.a[i] -= MAXN + 1;
            }
        }
        if(t.a[big]) t.len = big + 1;
        else t.len = big;
        return t;
    }

    BigInt operator * (const BigInt &T) const {
        BigInt res;
        int up;
        int te, tee;
        for (int i = 0; i < len; i ++) {
            up = 0;
            for (int j = 0; j < T.len; j ++) {
                te = a[i] * T.a[j] + res.a[i + j] + up;
                if(te > MAXN) {
                    tee = te - te/(MAXN + 1) * (MAXN + 1);
                    up = te / (MAXN + 1);
                    res.a[i + j] = tee;
                }else {
                    up = 0;
                    res.a[i + j] = te;
                }
            }
            if(up) res.a[i + T.len] = up;
        }
        res.len = len + T.len;
        while(res.len > 1 && res.a[res.len - 1] == 0) --res.len;
        return res;
    }

    

}dp[50][10], sum[50][50];

void print(BigInt s) {
    int len = s.len;
    printf("%d", s.a[len-1]);
    for (int i = len-2; i >= 0; i--) printf("%04d", s.a[i]);
}

BigInt max(BigInt a, BigInt b) {
    return a < b ? b : a;
}

int main(int argc, char *args[]) {
    fre();
    int n, k;
    scanf("%d %d", &n, &k);
    char s[50];
    scanf("%s", s);
    int len = strlen(s);
    for (int i = 1; i <= len; i ++) 
        for (int j = i; j <= len; j ++) 
            sum[i][j] = BigInt(s, i, j);
    for (int i = 1; i <= len; i ++) 
        dp[i][1] = BigInt(s, 1, i);
    for (int j = 2; j <= k; j ++) {
        for (int i = j; i < len; i ++) {
            for (int k = j - 1; k < i; k ++) {
                dp[i][j] = max(dp[i][j], dp[k][j-1] * sum[k+1][i]);
            }
        }
    }
    BigInt Max = BigInt();
    for (int i = k; i < len; i ++) 
        Max = max(Max, dp[i][k] * sum[i+1][len]);
    print(Max);
    return 0;
}

좋은 웹페이지 즐겨찾기