【测试题】sequence
题目
给定一个长度为n(n<=5000)的由['0'..'9']组成的字符串s,v[i,j]表示由字符串s第i到第j位组成的十进制数字。
将它的某一个上升序列定义为:将这个字符串切割成m段不含前导'0'的串,切点分别为k1,k2...km-1,使得v[1,k1]<v[k1+1,k2]<...<v[km-2,km-1]。
请你求出该字符串s的上升序列个数,答案对 10^9+7 取模。
题解
对于这种dp题,如果没有思路,我们可以先从最暴力的搜索开始分析,然后逐步优化
版本1
深搜枚举每一段的起点,搜完后逐段验证。
版本2
发现只要记录当前起点,终点,就可以描述出所有的后续状态,从而实现记忆化搜索。
版本3
把深搜改造成从后往前的dp,开两维记录起点、终点。时间复杂度:$O(n^3)$
版本4
把匹配过程改进,通过dp预处理出所有串的lcp,将匹配过程跳至不相等处。时间复杂度:$O(n^2)$
总结
设发$f[i][j]$表示起点为i,区间长度为j的方案数
那么本段范围为$[i,i+j)$,下一段的终点$>=i+j*2-1$
考虑状态转移:
若当前段比下一段小,则
$f[i][j] = f[i+j][j] + f[i+j][j+1] + ... + f[i+j][n-i]$
否则
$f[i][j] = f[i+j][j+1] + f[i+j][j+2] + ... + f[i+j][n-i]$
但是如果这样枚举会变成$O(n^3)$
我们可以使用后缀和来加速过程。
代码
#include <iostream>
#include <cstdio>
#define N 5001
#define int long long
#define mod (int)1e9+7
using namespace std;
char str[N];
int dp[N][N],n,lcp[N][N];
int compare(int a,int b)
{
int t=min(lcp[a][b],b-a-1);
return str[a+t]<str[b+t];
}
signed main()
{
cin>>n;
scanf("%s",str+1);
for(int i=n;i;i--)//lcp[i][j]表示从str[i,n]和str[j,n]的lcp
{
for(int j=i+1;j<=n;j++)
{
if(str[i]==str[j]) lcp[i][j]=lcp[i+1][j+1]+1;
}
}
for(int i=n;i;i--)//枚举起点
{
if(str[i]=='0') continue;
dp[i][n-i+1]=1;//起点到n划为一块
for(int j=1;j<=n-i;j++)//枚举区间长度,同时也是下一个起点的位置
{
if(compare(i,i+j)) dp[i][j]=dp[i+j][j];//等同于公式1
else dp[i][j]=dp[i+j][j+1];//等同于公式2
}
for(int j=n-i;j;j--)//维护后缀和
{
//cout<<dp[i][j]<<" ";
dp[i][j]+=dp[i][j+1],dp[i][j]%=mod;
}
//cout<<endl;
}
cout<<dp[1][1];
}
【测试题】sequence的更多相关文章
- oracle SEQUENCE 创建, 修改,删除
oracle创建序列化: CREATE SEQUENCE seq_itv_collection INCREMENT BY 1 -- 每次加几个 STA ...
- Oracle数据库自动备份SQL文本:Procedure存储过程,View视图,Function函数,Trigger触发器,Sequence序列号等
功能:备份存储过程,视图,函数触发器,Sequence序列号等准备工作:--1.创建文件夹 :'E:/OracleBackUp/ProcBack';--文本存放的路径--2.执行:create or ...
- DG gap sequence修复一例
环境:Oracle 11.2.0.4 DG 故障现象: 客户在备库告警日志中发现GAP sequence提示信息: Mon Nov 21 09:53:29 2016 Media Recovery Wa ...
- Permutation Sequence
The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of the p ...
- [LeetCode] Sequence Reconstruction 序列重建
Check whether the original sequence org can be uniquely reconstructed from the sequences in seqs. Th ...
- [LeetCode] Binary Tree Longest Consecutive Sequence 二叉树最长连续序列
Given a binary tree, find the length of the longest consecutive sequence path. The path refers to an ...
- [LeetCode] Verify Preorder Sequence in Binary Search Tree 验证二叉搜索树的先序序列
Given an array of numbers, verify whether it is the correct preorder traversal sequence of a binary ...
- [LeetCode] Longest Consecutive Sequence 求最长连续序列
Given an unsorted array of integers, find the length of the longest consecutive elements sequence. F ...
- [LeetCode] Permutation Sequence 序列排序
The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of the p ...
随机推荐
- php-微信分享签名
//测试 $APPID='*************************'; $SECRET='***********************'; $url = trim($_REQUEST['u ...
- docker系列之三:docker实际应用
以Docker为基础完成持续集成.自动交付.自动部署: 原理: RD推送代码到git 仓库或者svn等代码服务器上面,git服务器就会通过hook通知jenkins. jenkine 克隆git代码到 ...
- AAct 一款 KMS 激活工具
AAct是一款由俄罗斯网友Ratiborus制作的非常小巧实用的KMS激活工具,能自动设置密钥管理服务激活Windows.Office VL版本.支持手动安装及删除激活产品密钥.手动创建及删除续期计划 ...
- Nginx入门教程(转)
原文:https://www.cnblogs.com/qdhxhz/p/8910174.html nginx入门教程 一.概述 什么是nginx? Nginx (engine x) 是一款轻 ...
- 【1】【经典回溯、动态规划、贪心】【leetcode-55】跳跃游戏
给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个位置. 示例 1: 输入: [2,3,1,1,4]输出: true解释 ...
- 如何在ppt全屏演示时仍然显示任务栏?
相信做过ppt演讲的人会有这样的体会:有的时候希望全屏ppt时不要直接霸占全部的屏幕,至少希望能够看到任务栏,这样就可以仍然方便切换程序. 如何实现呢? 很简单,看下图吧:) https://www. ...
- vue学习整理
1.webpack+vue自定义路径别名 vue-cli 用的是webpack,也可以使用webpack自定义别名这个功能,自定义别名这个功能当你在多层文件夹嵌套的时候不必一层一层找路径,直接使用自定 ...
- jQuery(三)之 选择器(基础版)
对于jQuery的调用,我们一般都会传入参数 html: <div></div> js: console.log($('<a />')); console.log( ...
- Java 之 HashSet 集合
一.概述 java.util.HashSet 是 Set 接口的一个实现类,它所存储的元素是不可重复的,并且元素都是无序的(即存取顺序不一致). java.util.HashSet 底层的实现是一个 ...
- Android源码分析(三)-----系统框架设计思想
一 : 术在内而道在外 Android系统的精髓在源码之外,而不在源码之内,代码只是一种实现人类思想的工具,仅此而已...... 近来发现很多关于Android文章都是以源码的方向入手分析Androi ...