【LOJ#6074】子序列(动态规划)

题面

LOJ

题解

考虑一个暴力\(dp\)。

设\(f[i][c]\)表示当前在第\(i\)位,并且以\(c\)结尾的子序列个数。

那么假设当前位为\(a\),强制把\(a\)接在所有出现过的子序列后面,再加上一个单独的\(a\)。

也就是\(f[i][a]=\sum_j f[i-1][j]\),其他的\(f[i][k]=f[i-1][k]\)。

显然这样一个转移是可以写成矩阵形式的,预处理矩阵的前缀和和矩阵逆的前缀和就可以很方便的计算答案,这样子的复杂度是字符集大小三方的。

发现我们要的只是一个行向量或者一个列向量。这样子可以优化单次矩乘为字符集大小平方,然而我们直接按照\(dp\)转移就好了,就变成了字符集大小了。

那么最终的答案就是一个行向量和一个列向量相乘即可。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MOD 1000000007
#define MAX 100100
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
char s[MAX];
int n,Q;
int a[10][10],S[10],L[MAX][10],R[MAX][10];
int main()
{
scanf("%s",s+1);n=strlen(s+1);Q=read();
for(int i=0;i<=9;++i)a[i][i]=S[i]=R[0][i]=1;
for(int i=1;i<=n;++i)
{
int c=s[i]-96,tmp;
for(int j=0;j<=9;++j)tmp=a[j][c],a[j][c]=S[j],S[j]=(2ll*S[j]-tmp+MOD)%MOD;
for(int j=0;j<=9;++j)R[i][j]=S[j];
}
memset(a,0,sizeof(a));memset(S,0,sizeof(S));
for(int i=0;i<=9;++i)a[i][i]=1,L[0][i]=!i;
for(int i=1;i<=n;++i)
{
int c=s[i]-96,tmp;
for(int j=0;j<=9;++j)tmp=(a[c][j]+S[j])%MOD,S[j]=(S[j]-tmp+MOD)%MOD,a[c][j]=(a[c][j]+tmp)%MOD;
for(int j=0;j<=9;++j)L[i][j]=(a[0][j]+S[j])%MOD;
}
while(Q--)
{
int l=read(),r=read(),ans=MOD-1;
for(int i=0;i<=9;++i)ans=(ans+1ll*R[r][i]*L[l-1][i])%MOD;
printf("%d\n",ans);
}
return 0;
}

【LOJ#6074】子序列(动态规划)的更多相关文章

  1. LOJ #6074. 「2017 山东一轮集训 Day6」子序列

    #6074. 「2017 山东一轮集训 Day6」子序列 链接 分析: 首先设f[i][j]为到第i个点,结尾字符是j的方案数,这个j一定是从i往前走,第一个出现的j,因为这个j可以代替掉前面所有j. ...

  2. LOJ.6074.[2017山东一轮集训Day6]子序列(DP 矩阵乘法)

    题目链接 参考yww的题解.本来不想写来但是他有一些笔误...而且有些地方不太一样就写篇好了. 不知不觉怎么写了这么多... 另外还是有莫队做法的...(虽然可能卡不过) \(60\)分的\(O(n^ ...

  3. loj#6074. 「2017 山东一轮集训 Day6」子序列(矩阵乘法 dp)

    题意 题目链接 Sol 设\(f[i][j]\)表示前\(i\)个位置中,以\(j\)为结尾的方案数. 转移的时候判断一下\(j\)是否和当前位置相同 然后发现可以用矩阵优化,可以分别求出前缀积和逆矩 ...

  4. hdu1231最大连续子序列(动态规划)

    最大连续子序列 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

  5. HDU 6357.Hills And Valleys-字符串非严格递增子序列(LIS最长非下降子序列)+动态规划(区间翻转l,r找最长非递减子序列),好题哇 (2018 Multi-University Training Contest 5 1008)

    6357. Hills And Valleys 自己感觉这是个好题,应该是经典题目,所以半路选手补了这道字符串的动态规划题目. 题意就是给你一个串,翻转任意区间一次,求最长的非下降子序列. 一看题面写 ...

  6. 【ACM】最长公共子序列 - 动态规划

    最长公共子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列.tip:最长公共子序列也称作最 ...

  7. 最长上升子序列(动态规划递推,LIS)

    1759:最长上升子序列 题目: 总时间限制: 2000ms 内存限制: 65536kB 描述 一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的 ...

  8. C++求解汉字字符串的最长公共子序列 动态规划

        近期,我在网上看了一些动态规划求字符串最长公共子序列的代码.可是无一例外都是处理英文字符串,当处理汉字字符串时.常常会出现乱码或者不对的情况. 我对代码进行了改动.使用wchar_t类型存储字 ...

  9. [LeetCode] 300. 最长上升子序列 ☆☆☆(动态规划 二分)

    https://leetcode-cn.com/problems/longest-increasing-subsequence/solution/dong-tai-gui-hua-she-ji-fan ...

随机推荐

  1. Golang开发工具LiteIDE使用方法整理

    安装 参考github的说明 添加GOPATH 创建workspace 创建新文件 运行程序 Liteide中运行程序有两种方式: FR(FileRun)是编译并运行单个文件,可以使用Shift + ...

  2. LINUX操作系统(centos6.9)安装与配置

    LINUX操作系统(centos6.9)安装与配置_百度经验 https://jingyan.baidu.com/article/acf728fd6bdba1f8e510a3f7.html cento ...

  3. javascript中的 return false和return true

    关于javascript中的 return false和return true,return 是javascript里函数返回值的关键字,一个函数内处理的结果可以使用return 返回,这样在调用函数 ...

  4. laravel belongsTo使用

    前提:订单表(order)和用户表(user) 表结构: order CREATE TABLE `order` ( `id` char(16) COLLATE utf8mb4_unicode_ci N ...

  5. 遍历List过程中删除操作报java.util.ConcurrentModificationException错误

    1:遍历List 同时 remove 元素,出现java.util.ConcurrentModificationException错误 @Test public void test3(){ List& ...

  6. MBG逆向工程报错:generate failed: Exception getting JDBC Driver: com.mysql.jdbc.Driver

    修改pom文件,逆向工程如下: <!-- 逆向工程 --> <plugin> <groupId>org.mybatis.generator</groupId& ...

  7. java 静态成员访问

    public class MqConfig { @Getter private static IProducerProcessor callBackProducerRetry; @Getter @Va ...

  8. AngularJS从入门到精通

    第一 AngularJS的四大特性 1. MVC 例如:使用angularjs向模板传递数据 <!doctype html> <html> <head> <m ...

  9. 一个实际的案例介绍Spring Boot + Vue 前后端分离

    介绍 最近在工作中做个新项目,后端选用Spring Boot,前端选用Vue技术.众所周知现在开发都是前后端分离,本文就将介绍一种前后端分离方式. 常规的开发方式 采用Spring Boot 开发项目 ...

  10. IBM rational rose画时序图软件破解安装

    上边这个链接是开头的安装步骤,照着链接中的步骤安装完之后,接下来看下边. 1.然后安装完成打开软件“IBM Rational License Keyadministrator”.出现下图:选中第二项“ ...