D. New Year and Ancient Prophecy
time limit per test
memory limit per test
input
output
Limak is a little polar bear. In the snow he found a scroll with the ancient prophecy. Limak doesn't know any ancient languages and thus is unable to understand the prophecy. But he knows digits!
n
Limak assumes three things:
- strictly
- Every year is a positive integer number;
- There are no leading zeros.
109.
Input
n (1 ≤ n ≤ 5000) — the number of digits.
n. It's guaranteed that the first digit is not '0'.
Output
109.
Examples
input
6 123434
output
8
input
8 20152016
output
4
dp[i][j]表示第一个年为str[i]..str[j]时有多少种,cnt[i][j]表示以str[i], str[j]为两个字符串的开头时,第一个不同的字符的位置
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#define maxn 5005
#define MOD 1000000007
using namespace std;
typedef long long ll;
char str[maxn];
char s1[maxn],s2[maxn];
int n, dp[maxn][maxn];
int d[maxn][maxn];
void Init(){
for(int i = n-1; i >= 0; i--)
for(int j = n-1; j >= 0; j--)
if(str[i] != str[j])
d[i][j] = 0;
else
d[i][j] = d[i+1][j+1] + 1;
}
bool judge(int k1, int k2, int p1, int p2){
if(p2 - p1 > k2 - k1)
return true;
int p = d[k1][p1];
if(p > k2 - k1)
return false;
if(str[k1+p] < str[p1+p])
return true;
return false;
}
int main(){
// freopen("in.txt", "r", stdin);
scanf("%d%s", &n, str);
Init();
for(int i = n-1; i >= 0; i--){
if(str[i] != '0'){
dp[i][n-1] = 1;
int h = (i + n - 1) / 2;
if((i + n - 1) % 2 == 0)
h--;
for(int j = h; j >= i; j--){
if(str[j+1] != '0'){
for(int t = j+1+j-i; t < n; t++){
if((t == n-1 || str[t+1] != '0') && judge(i, j, j+1, t)){
dp[i][j] = ((ll)dp[i][j] + dp[j+1][t]) % MOD;
break;
}
}
}
}
for(int j = n-2; j >= i; j--)
dp[i][j] = ((ll)dp[i][j] + dp[i][j+1]) % MOD;
}
}
printf("%d\n", dp[0][0]);
return 0;
}