【27.34%】【codeforces 611D】New Year and Ancient Prophecy
time limit per test2.5 seconds
memory limit per test512 megabytes
inputstandard input
outputstandard 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!
One fragment of the prophecy is a sequence of n digits. The first digit isn’t zero. Limak thinks that it’s a list of some special years. It’s hard to see any commas or spaces, so maybe ancient people didn’t use them. Now Limak wonders what years are listed there.
Limak assumes three things:
Years are listed in the strictly increasing order;
Every year is a positive integer number;
There are no leading zeros.
Limak is going to consider all possible ways to split a sequence into numbers (years), satisfying the conditions above. He will do it without any help. However, he asked you to tell him the number of ways to do so. Since this number may be very large, you are only asked to calculate it modulo 109 + 7.
Input
The first line of the input contains a single integer n (1 ≤ n ≤ 5000) — the number of digits.
The second line contains a string of digits and has length equal to n. It’s guaranteed that the first digit is not ‘0’.
Output
Print the number of ways to correctly split the given sequence modulo 109 + 7.
Examples
input
6
123434
output
8
input
8
20152016
output
4
Note
In the first sample there are 8 ways to split the sequence:
“123434” = “123434” (maybe the given sequence is just one big number)
“123434” = “1” + “23434”
“123434” = “12” + “3434”
“123434” = “123” + “434”
“123434” = “1” + “23” + “434”
“123434” = “1” + “2” + “3434”
“123434” = “1” + “2” + “3” + “434”
“123434” = “1” + “2” + “3” + “4” + “34”
Note that we don’t count a split “123434” = “12” + “34” + “34” because numbers have to be strictly increasing.
In the second sample there are 4 ways:
“20152016” = “20152016”
“20152016” = “20” + “152016”
“20152016” = “201” + “52016”
“20152016” = “2015” + “2016”
【题解】
用记忆化搜索来搞;
int f(int x,int len);
表示当前的下标为x,然后把x->x+len-1这一段化为一段的方案数;
(这整个int可以理解为以x为左端点,长度不小于len的方案数);
一开始调用f(1,1);
表示获取以1为左端点,长度不小于1的方案数;
具体实现如下
int f(int x,int len)
{
if (s[x]=='0')//如果这个数字为0则范围方案数为0
return 0;
if (x+len-1 > n)//如果这一段划分超过了边界则无解
return 0;
if (x+len-1 == n)//如果恰好为n,那直接返回1
return 1;
if (ans[x][len]!=-1)//如果之前已经找过这个答案了;那么返回记录的答案;
return ans[x][len];
int ret = 0;
ret = f(x,len+1);//递归求解子问题比如f(1,2),f(1,3);
int a = get_lca(x,x+len);//这个表示以x..x+len-1这一段为一段;查看接下来要分那一段;这里的lca是x和x+len这两个位置后面相同的字符的个数->用于比较,从第一个不相同的数字开始比较
if (a>=len || (a<len && s[x+a]>=s[x+len+a]))//x+a和x+len+a分别是两个字符串第一个不同的位置的下标
ret+=f(x+len,len+1);//如果前面那个大于后面那个;则后面那个字符串只能通过增加一位长度来比它大
else
ret+=f(x+len,len);//否则,因为后面那个比较大,所以长度可以一样;
if (ret >= MOD) ret-=MOD;//加法的取模可以直接减掉;
ans[x][len] = ret;//记录答案;
return ret;
}
完整代码↓↓
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <string>
#define lson L,m,rt<<1
#define rson m+1,R,rt<<1|1
#define LL long long
using namespace std;
const int MAXN = 5010;
const int MOD = 1e9+7;
const int dx[5] = {0,1,-1,0,0};
const int dy[5] = {0,0,0,-1,1};
const double pi = acos(-1.0);
int n,lca[MAXN][MAXN],ans[MAXN][MAXN];
char s[MAXN];
void input_LL(LL &r)
{
r = 0;
char t = getchar();
while (!isdigit(t) && t!='-') t = getchar();
LL sign = 1;
if (t == '-')sign = -1;
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
r = r*sign;
}
void input_int(int &r)
{
r = 0;
char t = getchar();
while (!isdigit(t)&&t!='-') t = getchar();
int sign = 1;
if (t == '-')sign = -1;
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
r = r*sign;
}
int get_lca(int x,int y)
{
if (x > n || y>n)
return 0;
if (lca[x][y]!=-1)
return lca[x][y];
int ret = 0;
if (s[x]==s[y])
ret += get_lca(x+1,y+1)+1;
lca[x][y] = ret;
return ret;
}
int f(int x,int len)
{
if (s[x]=='0')
return 0;
if (x+len-1 > n)
return 0;
if (x+len-1 == n)
return 1;
if (ans[x][len]!=-1)
return ans[x][len];
int ret = 0;
ret = f(x,len+1);
int a = get_lca(x,x+len);
if (a>=len || (a<len && s[x+a]>=s[x+len+a]))
ret+=f(x+len,len+1);
else
ret+=f(x+len,len);
if (ret >= MOD) ret-=MOD;
ans[x][len] = ret;
return ret;
}
int main()
{
//freopen("F:\\rush.txt","r",stdin);
memset(lca,255,sizeof(lca));
memset(ans,255,sizeof(ans));
input_int(n);
scanf("%s",s+1);
printf("%d",f(1,1));
return 0;
}
【27.34%】【codeforces 611D】New Year and Ancient Prophecy的更多相关文章
- 【 BowWow and the Timetable CodeForces - 1204A 】【思维】
题目链接 可以发现 十进制4 对应 二进制100 十进制16 对应 二进制10000 十进制64 对应 二进制1000000 可以发现每多两个零,4的次幂就增加1. 用string读入题目给定的二进制 ...
- 【34.57%】【codeforces 557D】Vitaly and Cycle
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- 【27.91%】【codeforces 734E】Anton and Tree
time limit per test3 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【51.27%】【codeforces 604A】Uncowed Forces
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- 【27.85%】【codeforces 743D】Chloe and pleasant prizes
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【24.34%】【codeforces 560D】Equivalent Strings
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【34.88%】【codeforces 569C】Primes or Palindromes?
time limit per test3 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【27.66%】【codeforces 592D】Super M
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【27.40%】【codeforces 599D】Spongebob and Squares
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
随机推荐
- 关于http请求指定本地ip
static void Main(string[] args) { //ssl证书验证问题(没有校验) ServicePointManager.ServerCertificateValidationC ...
- Codeforces Round #100 E. New Year Garland (第二类斯特林数+dp)
题目链接: http://codeforces.com/problemset/problem/140/E 题意: 圣诞树上挂彩球,要求从上到下挂\(n\)层彩球.已知有\(m\)种颜色的球,球的数量不 ...
- 全面详细介绍一个P2P网贷领域的ERP系统的主要功能
一般的P2P系统,至少包括PC网站的前端和后端.前端系统的功能,可以参考"P2P系统哪家强,功能其实都一样" http://blog.csdn.net/fansunion/ ...
- Instruction-Set Support for Invocation of VMM-Configured Services without VMM Intervention
A processing core comprising instruction execution logic circuitry and register space. The register ...
- php websocket-网页实时聊天之PHP实现websocket(ajax长轮询和websocket都可以时间网络聊天室)
php websocket-网页实时聊天之PHP实现websocket(ajax长轮询和websocket都可以时间网络聊天室) 一.总结 1.ajax长轮询和websocket都可以时间网络聊天室 ...
- 26、从零写UVC驱动之分析描述符
指令:lsusb 可以查看usb设备的描述符信息,当然lsusb指令要带一些参数 一个usb设备有多个config配置+设备描述符,一个config有多个接口和association.config描述 ...
- Effective C++ 条款28
避免返回handles指向对象内部成分 本节作者讲述的知识核心是对于一个类来说,应该避免类返回自己内部的私有数据. 例如以下: class Point{ public: Point(int x, in ...
- HDU 2852 KiKi's K-Number 树状数组
先补充从n个数中求第k小数的理论知识........ 睡觉去~ ------------------------------------------又要睡觉的分割线------------------ ...
- 【u117】队列安排
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 一个学校里老师要将班上N个同学排成一列,同学被编号为1-N,他采取如下的方法: 1. 先将1号同学安排 ...
- 新版itunes添加铃声
iTunes 铃声制作-图文教程 ① 点选设备iPhone - 勾选手动管理音乐和视频 - 点击应用 注意:因本操作涉及iPhone内音乐和视频,请操作前先对音乐和视频进行相关备份,以免同步后被刷掉造 ...