CodeForces 611D:New Year and Ancient Prophecy DP + lcp

Portal

Title description

Given an n-digit number, it is required to split the n-digit number into several numbers, and it must meet:

  • The order of the numbers must be strictly increasing
  • The numbers are all positive integers
  • No leading zeros
  • Find the number of all possible solutions

analysis

This question has been written for several days. 2333
First, how to judge the two A and B which is larger and which is smaller.
First, if the length of A is greater than the length of B, A is greater than B, and vice versa.
If the length of AB is the same, compare the longest common between them Prefix. If it is equal to the length of AB, it means that A is equal to B. If it is not equal, then compare the next bit of the strongest common prefix.

We use the array dp[i][j] to represent the first i digits, if the length of the last number is j, there are two cases:

  1. If the length of the previous section of j is less than j, it means that it is definitely less than the last and less than the last j digits, and the transfer can be made directly (prefix and optimization can be used)
  2. If the length of the previous section of j is equal to j, then it is necessary to determine whether it is legal, determine the size of the two strings, and then perform state transition

Finally, maintain the prefix and

Code

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstring>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define _CRT_SECURE_NO_WARNINGS
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
const int INF = 0x3f3f3f3f;
const int N = 5e3 + 10;
const ll mod = 1e9 + 7;
int lcp[N][N];
char str[N];
int n;
int sum[N][N];
ll dp[N][N];


void LCP(){
    
    
    for(int i = n;i;i--)
        for(int j = n;j;j--)
            if(str[i] == str[j])
                lcp[i][j] = lcp[i + 1][j + 1] + 1;
}

bool is(int x,int y){
    
    
    return str[x + lcp[x][y]] < str[y + lcp[x][y]];
}

void solve(){
    
    
    for(int i = 0;i <= n;i++) sum[0][i] = 1;
    for(int i = 1;i <= n;i++){
    
    
        for(int j = 1;j <= i;j++){
    
    
            int len = i - j + 1;
            if(str[len] == '0') continue;
            dp[i][j] = (dp[i][j] + sum[len - 1][j - 1]) % mod;
            int s = len - j;
            if(s < 1) continue;
            if(is(s,len) && lcp[s][len] < j)
                dp[i][j] = (dp[i][j] + dp[len - 1][j]) % mod;
        }
        for(int j = 1;j <= n;j++)
            sum[i][j] = (sum[i][j - 1] + dp[i][j]) % mod;
    }

}

int main(){
    
    
    scanf("%d",&n);
    scanf("%s",str + 1);
    LCP();
    solve();
    ll ans = 0;
    for(int i = 1;i <= n;i++) ans = (ans + dp[n][i]) % mod;
    printf("%lld\n",ans);
    return 0;
}

/**
*  ┏┓   ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃       ┃
* ┃   ━   ┃ ++ + + +
*  ████━████+
*  ◥██◤ ◥██◤ +
* ┃   ┻   ┃
* ┃       ┃ + +
* ┗━┓   ┏━┛
*   ┃   ┃ + + + +Code is far away from  
*   ┃   ┃ + bug with the animal protecting
*   ┃    ┗━━━┓ 神兽保佑,代码无bug 
*   ┃        ┣┓
*    ┃        ┏┛
*     ┗┓┓┏━┳┓┏┛ + + + +
*    ┃┫┫ ┃┫┫
*    ┗┻┛ ┗┻┛+ + + +
*/


Guess you like

Origin blog.csdn.net/tlyzxc/article/details/112727359