[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. 深copy和浅copy

    浅copy:其实就是将容器中的内存地址存放进另一个容器中,所以两个容器本身的内存地址不相同,但容器里面的内存地址相同 代码如下: 深copy:就是从里到外完完全全复制了所有值,存进另外的内存空间,并赋 ...

  2. Canvas 图片平铺设置

    /** * 图片平铺 */ function initDemo7(){ var canvas = document.getElementById("demo7"); if (!ca ...

  3. Entity Framework(三)---FluentAPI和增删查改

    一.FluentAPI: 1.基本配置: namespace ConsoleApp14.ModelConfig { public class PersonConfig: EntityTypeConfi ...

  4. (原)UE4.20 自定义编辑器 - 基础(一)创建编辑器模块

            @author:白袍小道 前言: 本小文参考了UnrealC++,游戏编辑器(应该都找不到了嘿嘿)等书籍. 引擎基于UnrealEngine4.20版本(由于UnrealC++ 用的是 ...

  5. 使用Cookie保存用户和密码然后自动登录

    login.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  6. Hexo添加字数统计、阅读时长

    统计插件 配置 NexT 主题默认已经集成了文章[字数统计].[阅读时长]统计功能,如果我们需要使用,只需要在主题配置文件 _config.yml 中打开 wordcount 统计功能即可.如下所示: ...

  7. nginx限速白名单配置

    在<nginx限制连接数ngx_http_limit_conn_module模块>和<nginx限制请求数ngx_http_limit_req_module模块>中会对所有的I ...

  8. 用HTML5绘制的一个星空特效图

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. CSU 2130~湖南多校对抗第八场 C

    2130: Permutations Submit Page   Summary   Time Limit: 1 Sec     Memory Limit: 128 Mb     Submitted: ...

  10. hashCode()方法和equals方法的重要性。

    在Object中有两个重要的方法:hashCode()和equals(Object obj)方法,并且当你按ctrl+alt+s时会有Generator hashCode()和equals().我们不 ...