• luogu1415 拆分数列


    题目大意

      给出一列数字,需要你添加任意多个逗号将其拆成若干个严格递增的数。如果有多组解,则输出使得最后一个数最小的同时,字典序最大的解(即先要满足最后一个数最小;如果有多组解,则使得第一个数尽量大;如果仍有多组解,则使得第二个数尽量大,依次类推……)。

    题解

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int MAX_N = 510;
    int A[MAX_N];
    int F1[MAX_N], F2[MAX_N], AnsF2[MAX_N];
    int N;
    
    void CharToA(char *s)
    {
        N = strlen(s + 1);
        for (int i = 1; i <= N; i++)
            A[i] = s[i] - '0';
    }
    
    bool RangeLt(int l1, int r1, int l2, int r2)
    {
        while (A[l1] == 0 && l1 <= r1)
            l1++;
        while (A[l2] == 0 && l2 <= r2)
            l2++;
        if (r1 - l1 != r2 - l2)
            return r1 - l1 < r2 - l2;
        else
            for (int i = 0; i <= r1 - l1; i++)
                if (A[l1 + i] != A[l2 + i])
                    return A[l1 + i] < A[l2 + i];
        return false;
    }
    
    void DP1()
    {
        for (int i = 1; i <= N; i++)
            F1[i] = 1;
        for (int i = 1; i <= N; i++)
            for (int j = 2; j <= i; j++)
                if (RangeLt(F1[j - 1], j - 1, j, i))
                    F1[i] = j;
    }
    
    void DP2(int ed)
    {
        memset(F2, 0, sizeof(F2));
        F2[ed] = N;
        for (int i = ed - 1; i >= 1; i--)
            for (int j = i; j <= ed - 1; j++)
                if (RangeLt(i, j, j + 1, F2[j + 1]))
                    F2[i] = j;
    }
    
    bool CmpF2()
    {
        int cur = 1;
        while (cur <= N)
        {
            if (F2[cur] != AnsF2[cur])
                return F2[cur] > AnsF2[cur];
            cur = F2[cur] + 1;
        }
        return false;
    }
    
    void Print()
    {
        int cur = 1;
        bool tag = false;
        while (cur <= N)
        {
            if (tag)
                putchar(',');
            tag = true;
            for (int i = cur; i <= AnsF2[cur]; i++)
                putchar('0' + A[i]);
            cur = AnsF2[cur] + 1;
        }
    }
    
    int main()
    {
        char s[MAX_N];
        scanf("%s", s + 1);
        CharToA(s);
        DP1();
        DP2(F1[N]);
        memcpy(AnsF2, F2, sizeof(F2));
        for (int i = F1[N] - 1; A[i] == 0; i--)
        {
            if (!RangeLt(F1[i - 1], i - 1, i, N))
                break;
            DP2(i);
            if (CmpF2())
                memcpy(AnsF2, F2, sizeof(F2));
        }
        Print();
        return 0;
    }
    

      

  • 相关阅读:
    image 和 barplot 的组合
    par函数mgp 参数-控制坐标轴的位置
    R语言绘图时的边界碰撞问题
    R语言绘制花瓣图flower plot
    mothur 计算稀释性曲线
    R语言 vegan包计算物种累计曲线
    R语言数据框小技巧
    tophat-fusion 鉴定融合基因
    FusionCancer-人类癌症相关的融合基因的数据库
    rrnDB数据库简介-16S基因多拷贝数的证据
  • 原文地址:https://www.cnblogs.com/headboy2002/p/9479310.html
Copyright © 2020-2023  润新知