luogu1018【2000提高】乘积最大(区间dp)

来源:互联网 发布:lol代练接单软件 编辑:程序博客网 时间:2024/06/06 01:16

dp[i][k]表示在1..i切k刀,分成k+1部分的最大乘积。a[i][j]表示s[i…j]这个数。状态数O(nm),预处理O(n2),决策O(n),转移O(1),总的时间复杂度O(n2m)。按照题目叙述应该高精,太懒没写。。居然水过。。。嗯,noip嘛,骗分就好了。
upd:最新版看这里:传送门

#include <cstdio>#include <cstring>#include <iostream>#define ll long longusing namespace std;int const N=41;int n,m;ll s,a[N][N],dp[N][7];int main(){//  freopen("multmax.in","r",stdin);//  freopen("multmax.out","w",stdout);    scanf("%d%d",&n,&m);scanf("%lld",&s);    for(int i=n;i>=1;--i) a[i][i]=s%10,s/=10;    for(int i=1;i<n;i++)        for(int j=i+1;j<=n;j++) a[i][j]=a[i][j-1]*10+a[j][j];    for(int i=1;i<=n;i++) dp[i][0]=a[1][i];    for(int k=1;k<=m;k++)//砍k刀         for(int i=k+1;i<=n;i++)//在前i个砍             for(int j=k;j<i;j++)                 dp[i][k]=max(dp[i][k],dp[j][k-1]*a[j+1][i]);    printf("%lld",dp[n][m]);    return 0;}