[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. 查看Linux系统用户登录日志

    日志: /var/log/wtmp说明: 此文件是二进制文件,查看方法如下:该日志文件永久记录每个用户登录.注销及系统的启动.停机的事件.因此随着系统正常运行时间的增加,该文件的大小也会越来越大,增加 ...

  2. 求 n的阶乘

    def chengji(n): if n == 0: return 1 return chengji(n-1)*nprint(chengji(n))

  3. python pyinstaller 打包程序报错解决

    python打包exe,各种入坑 一.安装PyInstaller 1.安装pywin32 pip命令安装:pip install pywin32(推荐) 2.安装Pyinstaller pip命令安装 ...

  4. sklearn中predict()与predict_proba()用法区别

    predict是训练后返回预测结果,是标签值. predict_proba返回的是一个 n 行 k 列的数组, 第 i 行 第 j 列上的数值是模型预测 第 i 个预测样本为某个标签的概率,并且每一行 ...

  5. Qt(1)

    Qt Qt开发图形界面软件,可以跨win.linux.mac平台.移动端,使用c++开发 Qt采用所见即所得的UI设计(UI设计和代码是联动的),GUI界面编辑信号和槽,由开发环境自动生成c++代码, ...

  6. 椭圆曲线加密和rsa对比

    最近在导师的要求下接手了基于欧洲标准的车联网项目中的安全层,需要学习密码学,以及网络安全的相关内容,这里做一个总结 引用的大部分内容为一个西安的大佬(哈哈我老家也是西安的),大佬主页:https:// ...

  7. NodeJs04

    REST API的设计 前言 客户端通过请求URL,传递参数,去获取指定的数据,这就是API(ApplicationProgramInterface). API是前端和客户端操作后端数据的一种方式,一 ...

  8. Java进行身份证格式强校验(准)

    最近做了一个系统,涉及到对用户输入的身份证号进行校验,减少脏数据传入后台处理并降低企业验证成本,因此在接入层便对输入信息做格式强校验. 直接附上代码,可直接使用. package hope.ident ...

  9. vue项目--favicon设置以及动态修改favicon

    最近写公司项目时,动态更新favicon 动态更新之前需要有一个默认的favicon. 目前vue-cli搭建的vue项目里面已经有了一个static文件夹,存放静态文件. favicon图片放到该文 ...

  10. quartz 调度

    1.POI文件中导入包      <dependency> <groupId>org.quartz-scheduler</groupId> <artifact ...