【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 ...
随机推荐
- crm2013 查看下拉框的选项
在CRM2011中,我们非常easy查看下拉框的选择.打开页面,按F12.把光标对准目标,就会显示出详细的选项,如图:' watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi ...
- SpringMVC实战(三种控制器方式)
1.前言 上篇博客着重说了一下SpringMVC中几种处理映射的方式,这篇博客来说一下SpringMVC中几种经常使用的控制器. 2.经常使用控制器 2.1 ParameterizableViewC ...
- vue 用 :style动态修改带中划线的样式属性
今天在项目中遇到要用:style动态设置margin-top值,直接写发现报错.后来改成驼峰就成功了,记录一下 错误示范: <div class="testLeft ulData&qu ...
- 组件绑定v-model,实现最大化复用
看优秀的vue项目,对组件的封装做的都非常到位,比如一个按钮都可以实现复用,仔细研究会发现实现基础就是组件直接绑定v-model,来看看按钮: 比如有个点赞按钮,长这样: 当点赞之后变成这样: 相信很 ...
- 结合Wireshark捕获分组深入理解TCP/IP协议栈之TCP协议(TCP报文格式+三次握手实例)
摘要: 本文简单介绍了TCP面向连接理论知识,详细讲述了TCP报文各个字段含义,并从Wireshark俘获分组中选取TCP连接建立相关报文段进行分析. 一.概述 TCP是面向连接的可靠 ...
- vue学习笔记一:用Key管理可复用元素
vue为了高效的渲染元素,会尽可能的复用组件,而不是从头渲染,如下案例 <template> <div id="app"> <template v-i ...
- 又在折腾cygwin
apt-cyg https://github.com/transcode-open/apt-cyg/blob/master/README.md cygwin 163镜像 http://mirrors. ...
- FFTW库+VS2012配置
配置环境:Windows7+VS2012 下载资源包,解压后例如以下图: 要嵌入VS2012中,须要相应的lib文件,于是接下来使用VS2012来生成相应的lib文件 在VS2012/Common7/ ...
- js中json数据简单处理(JSON.parse()和js中嵌套html)
js中json数据简单处理(JSON.parse()和js中嵌套html) 一.总结 1.html中嵌套js:<script>js代码</script> 2.js中嵌套html ...
- 【27.85%】【codeforces 743D】Chloe and pleasant prizes
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...