zoukankan      html  css  js  c++  java
  • 洛谷P1415 拆分数列(dp)

    洛谷P1415 拆分数列

    做两次dp求解。

    (T(i,j)) 表示从原数列下标 (i) 取到 (j) 的数字组成的数。

    (d[i]) 表示前 (i) 个数字分成任意多个递增数且最后的数最小时,最后的数为 (T(d[i],i)) 。初始化 (d[i] = 1) ,转移方程式为 (d[i] = max {j | T(d[j-1],j-1) < T(j,i) })

    (f[i]) 表示从 (i) 开始的序列第一个数最大的终止下标 (f[i]) ,转移方程式为 (f[i]=max {j | T(i,j)<T(j+1,f[j+1]) })

    注意最后一个数有前导零时存在细节问题,如数据 (1234050) 应划分为 (12,34,050)

    解决方法是把最后一个数前面的前导 (0)(f) 值都指向 (n)

    打印时从 (1) 开始沿 (f) 打印答案。

    时间复杂度为 (O(n^3)) ,由于数据大部分为随机,实际运行效率接近 (O(n^2))

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    
    using namespace std;
    
    typedef long long ll;
    const int N=505,INF=2e9+5;
    char s[N];
    int n,a[N];
    
    bool small(int l1,int r1,int l2,int r2){
        while(l1<=r1&&a[l1]==0) l1++;
        while(l2<=r2&&a[l2]==0) l2++;
    
        if(r1-l1+1==0||r2-l2+1==0) return false;
        if(r1-l1+1<r2-l2+1) return true;
        if(r1-l1+1>r2-l2+1) return false;
    
        int len=r1-l1+1;
        for(int i=0;i<len;i++){
            if(a[l1+i]<a[l2+i]) return true;
            if(a[l1+i]>a[l2+i]) return false;
        }
        return false;
    }
    int d[N];
    void dp1(){
        for(int i=1;i<=n;i++){
            d[i]=1;
            for(int j=i;j>=1;j--)
                if(small(d[j-1],j-1,j,i)) {d[i]=j;break;}
        }
    }
    int f[N];
    void dp2(){
        f[d[n]]=n;int zero=d[n];
        /******/
        while(a[zero-1]==0) f[zero-1]=n,zero--;
        for(int i=d[n]-1;i>=1;i--){
            for(int j=d[n]-1;j>=i;j--)
                if(small(i,j,j+1,f[j+1])) {f[i]=j;break;}
        }
    }
    int main(){
        scanf("%s",s+1);
        n=strlen(s+1);
        for(int i=1;i<=n;i++) a[i]=s[i]-'0';
        dp1();
        dp2();
        int pos=1,flag=0;
        while(pos<=n){
            if(flag) putchar(',');
            flag=1;
            for(int i=pos;i<=f[pos];i++) printf("%d",a[i]);
            pos=f[pos]+1;
        }
    }
    
  • 相关阅读:
    遇到一个php解析错误
    wndows netsh winsock reset
    javascript 阻塞
    ci 文件类型错误xlsx
    input限制整数
    canvas 时钟转动
    JS实现别踩白块游戏
    本地存储技术localStorage
    JavaScript事件
    JavaScript实现放大镜效果
  • 原文地址:https://www.cnblogs.com/solvit/p/11383384.html
Copyright © 2011-2022 走看看