[pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=61891436

向大(hei)佬(e)势力学(di)习(tou)

Description





Input

第一行包含两个整数n, m,分别表示上下两个管道中球的数目。 第二行为一个AB字符串,长度为n,表示上管道中从左到右球的类型。其中A表示浅色球,B表示深色球。 第三行为一个AB字符串,长度为m,表示下管道中的情形。

Output

仅包含一行,即为 Sigma(Ai^2) i从1到k 除以1024523的余数。

Sample Input

2 1

AB

B

Sample Output

5

HINT

样例即为文中(图3)。共有两种不同的输出序列形式,序列BAB有1种产生方式,而序列BBA有2种产生方式,因此答案为5。

【大致数据规模】

约30%的数据满足 n, m ≤ 12;

约100%的数据满足n, m ≤ 500。

一眼就被sigma吓傻了,以为是一道数论题,分析来分析去,好不容易把题目中的等式理解了,却对着ai^2不知所措

(以下是大佬把我讲懂的)

仔细分析,ai表示第i种输出序列的方案数,那么ai^2就是ai*ai,感觉像不像两个人玩这个游戏得到相同输出的方案数?由此一来就有些思路可循了

我们设dp[i][j][k][l]表示第一个人从上排取i个,下排取j个,第二个人上排取k个,下排取l个。转移方程即为(a[]为上排b[]为下排):

1、a[i]==a[k] , dp[i][j][k][l]+=dp[i-1][j][k-1][l];

2、a[i]==b[l] , dp[i][j][k][l]+=dp[i-1][j][k][l-1];

3、b[j]==a[k], dp[i][j][k][l]+=dp[i][j-1][k-1][l];

4、b[j]==b[l], dp[i][j][k][l]+=dp[i][j-1][k][l-1];

但是这个四维的方程要TLE啊,怎么办呢?我们想想能不能减少一维的枚举,于是可以发现:因为要保证第一个人和第二个人的输出序列一样,那么取的球的数量一定一样,即可改一下dp数组的定义,dp[i][j][k],l可用i+j-k来表示。

然后我就wa了,为什么呢?

因为空间要爆,大佬告诉我要开滚动,看看ijk都是由-1转移过来的,那么任选一个都可以吧?果断选了k……然而在for循环中,k是最后枚举的,k对应了很多值,mod2之后就重复对应了……

听大佬的建议,我把dp重新定义为了 两个人都取了i个球,第一个人去j个上排,第二个人取k个上排,然后i开滚动

现在想来应该可以不用改dp定义,直接i开滚动也行,因为i是第一个for的,不至于会出事

初值也是挺有讲究的东西

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int N=500+5;
const int mod=1024523; int n,m;
char c[N],d[N],a[N],b[N];
int dp[2][N][N]; int main(){
scanf("%d%d",&n,&m);
scanf("%s%s",c+1,d+1);
for(int i=1;i<=n;i++){
a[n-i+1]=c[i];
}
for(int i=1;i<=m;i++){
b[m-i+1]=d[i];
}
dp[0][0][0]=1;
for(int i=1;i<=n+m;i++){
for(int j=max(0,i-m);j<=min(i,n);j++){
for(int k=max(0,i-m);k<=min(i,n);k++){
dp[i%2][j][k]=0;//在滚啊,上一次的值要清零
if(a[j]==a[k]&&j-1>=0&&k-1>=0) dp[i%2][j][k]=(dp[i%2][j][k]+dp[(i-1)%2][j-1][k-1])%mod;
if(i-k<=m&&a[j]==b[i-k]&&j-1>=0) dp[i%2][j][k]=(dp[i%2][j][k]+dp[(i-1)%2][j-1][k])%mod;
if(i-j<=m&&b[i-j]==a[k]&&k-1>=0) dp[i%2][j][k]=(dp[i%2][j][k]+dp[(i-1)%2][j][k-1])%mod;
if(i-j<=m&&i-k<=m&&b[i-j]==b[i-k]) dp[i%2][j][k]=(dp[i%2][j][k]+dp[(i-1)%2][j][k])%mod;
}
}
}
printf("%d",(dp[(m+n)%2][n][n])%mod);
return 0;
}

总结:

1、灵活的根据某些性质降维

2、开滚动数组的时候要注意开法,不能互相影响

3、如果滚动数组不是直接赋值覆盖的话,需要清零

【bzoj1566】【管道取珠】竟然是dp题(浅尝ACM-E)的更多相关文章

  1. 洛谷1758 BZOJ1566 管道取珠题解

    题目链接 一道人类智慧的dp题 首先我们可以将∑ai^2转化为求取两次,两次一样的方案数 然后用f[i][j][k][l]表示第一个人在第一个串中取到i第二个串中取到j 第二个人在一个串中取到k第二个 ...

  2. 【BZOJ1566】【NOI2009】管道取珠(动态规划)

    [BZOJ1566][NOI2009]管道取珠(动态规划) 题面 BZOJ 题解 蛤?只有两档部分分.一脸不爽.jpg 第一档?爆搜,这么显然,爆搜+状压最后统计一下就好了 #include<i ...

  3. BZOJ1566 【NOI2009】管道取珠

    题面 这是一道DP神题,直到我写下这句题解时也没有想明白…… 首先,这道题要我们求所有(不同输出序列的方案数)的平方和,于是我们当然就想到求所有不同输出序列的方案数……(大雾) .这道题一个巧妙的地方 ...

  4. 【BZOJ 1566】 1566: [NOI2009]管道取珠 (DP)

    1566: [NOI2009]管道取珠 Time Limit: 20 Sec  Memory Limit: 650 MBSubmit: 1659  Solved: 971 Description In ...

  5. Bzoj 1566: [NOI2009]管道取珠(DP)

    1566: [NOI2009]管道取珠 Time Limit: 20 Sec Memory Limit: 650 MB Submit: 1558 Solved: 890 [Submit][Status ...

  6. 动态规划:NOI 2009 管道取珠

    [NOI2009] 管道取珠 输入文件:ballb.in   输出文件:ballb.out   简单对比 时间限制:1 s   内存限制:512 MB #include <iostream> ...

  7. BZOJ 1566 【NOI2009】 管道取珠

    题目链接:管道取珠 这道题思路还是很巧妙的. 一开始我看着那个平方不知所措……看了题解后发现,这种问题有一类巧妙的转化.我们可以看成两个人来玩这个游戏,那么答案就是第二个人的每个方案在第一个人的所有方 ...

  8. NOI2009 管道取珠 神仙DP

    原题链接 原题让求的是\(\sum\limits a_i^2\),这个东西直接求非常难求.我们考虑转化一下问题. 首先把\(a_i^2\)拆成\((1+1+...+1)(1+1+...+1)\),两个 ...

  9. BZOJ 1566 管道取珠(DP)

    求方案数的平方之和.这个看起来很难解决.如果转化为求方案数的有序对的个数.那么就相当于求A和B同时取,最后序列一样的种数. 令dp[i][j][k]表示A在上管道取了i个,下管道取了j个,B在上管道取 ...

  10. BZOJ.1566.[NOI2009]管道取珠(DP 思路)

    BZOJ 洛谷 考虑\(a_i^2\)有什么意义:两个人分别操作原序列,使得得到的输出序列都为\(i\)的方案数.\(\sum a_i^2\)就是两人得到的输出序列相同的方案数. \(f[i][j][ ...

随机推荐

  1. 深入理解net core中的依赖注入、Singleton、Scoped、Transient(四)【转】

    原文链接:https://www.cnblogs.com/gdsblog/p/8465401.html 相关文章: 深入理解net core中的依赖注入.Singleton.Scoped.Transi ...

  2. 团队Alpha版本冲刺(四)

    目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:丹丹 组员7:何家伟 组员8:政演 组员9:鸿杰 组员10:刘一好 组员:何宇恒 展示组内最新 ...

  3. Thread 线程池

    Thread 线程池: 当使用多个较短存活期的线程有利时,运用线程池技术可以发挥作用.运用这一技术时,不是为每个任务创建一个全新的线程,而可以从线程池中抽出线程,并分配给任务.当线程完成任务后,再把它 ...

  4. BeanUtils Date

    在jdbc封装(基础的CRUD)的时候(查询一条数据,查询多条数据,更新....)经常会用到一个BeanUtil来设置属性值,当对象中存在Date类型的时候,会报错:如下: 2017-11-03 13 ...

  5. [THUWC2017][bzoj5020] 在美妙的数学王国中畅游 [LCT+泰勒展开]

    题面 LOJ传送门 思路 这里很重要 它提示我们,把给定的三个函数泰勒展开,并用LCT维护每一项泰勒展开式的值,维护十几项就满足了题目的精度要求 我们考虑一个函数在0位置的泰勒展开 $f(x)=\su ...

  6. 性能优化-使用 RAIL 模型评估性能

    RAIL 是一种以用户为中心的性能模型.每个网络应用均具有与其生命周期有关的四个不同方面,且这些方面以不同的方式影响着性能: TL;DR 以用户为中心:最终目标不是让您的网站在任何特定设备上都能运行很 ...

  7. Nodejs 基础知识 浅析

    1. 模块化 ①常用模块化规范 CommonJS + nodejs AMD(Asynchronous Module Definition) + RequireJS CMD(Common Module ...

  8. 洛谷P1450 [HAOI2008]硬币购物

    题目描述 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. 输入输出格式 输入格式: 第一 ...

  9. SQL Server 中使用 Try Catch 处理异常

    CREATE TABLE ErrorLog( errNum INT, ErrSev ), ErrState INT, ErrProc ), ErrLine INT, ErrMsg ) ) CREATE ...

  10. Python’s super() considered super!

    如果你没有被Python的super()惊愕过,那么要么是你不了解它的威力,要么就是你不知道如何高效地使用它. 有许多介绍super()的文章,这一篇与其它文章的不同之处在于: 提供了实例 阐述了它的 ...