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;
}

  

猜你喜欢

转载自www.cnblogs.com/headboy2002/p/9479310.html
今日推荐