NOIp2000 乘积最大

高精度计算DP优化
针对一个涉及高精度计算的问题,采用动态规划方法求解。利用自定义的高精度类克服了__int128的限制,通过DP状态转移方程进行优化计算。

原blog地址

Luogu

题目是真的坑,__int128都会被卡掉,所以我直接去网上搞了个高精度的类。

\(dp[i,j]\) 为将前 \(j\) 个数用 \(i\) 个乘号乘起来的最优解。

\(A[i,j]\) 为从第 \(i\) 个数开始到第 \(j\) 个数拼起来的数。

\[dp[i,j]=\max_{i-1+[i=1]≤k<j} \{dp[i-1,k]*A[k+1,j]\}\]

为了视觉效果,我就直接扔上来 \(60\)long long代码好了

#include <iostream>
#include <cstdio>

const int max_n = 40 + 4;
const int max_k = 6 + 4;

int N, K;

long long Dp[max_k][max_n], A[max_n][max_n];

char Num[max_n];

int main()
{
    scanf("%d %d", &N, &K);
    scanf("%s", &Num[1]);
    for(int i = 1; i <= N; ++i)
    {
        Num[i] -= '0';
        Dp[0][i] = Dp[0][i - 1] * 10 + Num[i];
    }
    for(int i = 1; i <= N; ++i)
        for(int j = i; j <= N; ++j)
            A[i][j] = A[i][j - 1] * 10 + Num[j];
    for(int i = 1; i <= K; ++i)
        for(int j = i + 1; j <= N; ++j)
            for(int k = (i == 1) ? 1 : i - 1; k < j; ++k)
                Dp[i][j] = std::max(Dp[i][j], Dp[i - 1][k] * A[k + 1][j]);
    printf("%lld\n", Dp[K][N]);
    return 0;
        
}

转载于:https://www.cnblogs.com/zcdhj/p/8505448.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值