zoukankan      html  css  js  c++  java
  • 洛谷P1018乘积最大——区间DP

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

    区间DP+高精,注意初始化和转移的细节。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define MAXN 20005
    using namespace std;
    typedef long long ll;
    ll n,k,a[45],f[45][7][MAXN],tmp[MAXN],num[MAXN];
    char dc[45];
    void nm(ll l,ll r)
    {
    //    printf("l=%lld r=%lld
    ",l,r);
        num[0]=r-l+1;
        for(ll i=l;i<=r;i++)//正存即可 
            num[i-l+1]=a[i];
    //    for(int i=1;i<=num[0];i++)printf("%lld",num[i]);
    //    cout<<endl;
    }
    void init()
    {
        a[0]=strlen(dc);
        for(ll i=1;i<=a[0];i++)
        {
            a[i]=dc[a[0]-i]-'0';
    //        memset(num,0,sizeof num);
    //        nm(1,i);
            memcpy(f[i][0],f[i-1][0],sizeof f[i-1][0]);//注意初始化! 
            f[i][0][0]++;f[i][0][i]=a[i];
        }
    }
    void ch(ll a[],ll b[])
    {
        tmp[0]=a[0]+b[0]-1;
        for(ll i=1;i<=a[0];i++)
            for(ll j=1;j<=b[0];j++)
            {
                tmp[i+j-1]+=a[i]*b[j];
                tmp[i+j]+=tmp[i+j-1]/10;
                tmp[i+j-1]%=10;
            }
        if(tmp[tmp[0]+1])tmp[0]++;
    }
    bool com(ll a[],ll b[])
    {
        if(a[0]>b[0])return 1;
        if(a[0]<b[0])return 0;
        for(ll i=a[0];i;i--)
        {
            if(a[i]>b[i])return 1;
            if(a[i]<b[i])return 0;
        }
        return 0;
    }
    void print(ll a[])
    {
        for(ll i=a[0];i;i--)
            printf("%lld",a[i]);
    }
    int main()
    {
        scanf("%lld%lld",&n,&k);
        cin>>dc;
        init();
    //    f[1][1][0]=1;f[1][1][1]=1;
        for(ll i=2;i<=n;i++)
            for(ll l=1;l<=min(i-1,k);l++)
                for(ll j=l;j<i;j++)//从l开始!!!
                {
    //                f[i][l]=max(f[j][l-1]*num(j+1,i),f[i][l]);
                    memset(tmp,0,sizeof tmp);
                    memset(num,0,sizeof num);
                    nm(j+1,i);
                    ch(f[j][l-1],num);
                    if(com(tmp,f[i][l]))memcpy(f[i][l],tmp,sizeof tmp);
                }
        print(f[n][k]);
        return 0;
    }
  • 相关阅读:
    链接数据库
    Ajax 密码验证
    for循环 打印菱形 空 和 实
    for 循环 正方形
    面向对象
    用正则表达式 匹配手机号码
    正则表达式
    js 中 == 和=== 有什么区别?
    js 删除
    封装函数增删改查
  • 原文地址:https://www.cnblogs.com/Zinn/p/8533365.html
Copyright © 2011-2022 走看看