Luogu1758

DarkBZOJ1566

题解

因为他要让我们求出每种状态出现次数的平方和,这样模拟两人取球的时候,设第一个人取球的方案为A,第二个人取球的方案为B,

这样对于每一个A,都有C(n + m , n)种B的方案与之对应,所以这样求出来正好是每种状态出现次数的平方和

所以方案数的平方和转化为选两次结果一样的方案数

我们用f[i][j][k][l]表示两个人同时取出了i+j个球,第一个人第1行取了i个球,第二行取了j个球,第二个人第1行取了k个球,第二行取了l个球

省掉一维,再用滚动数组

/*
f[i][j][k]表示第1种方案第一行选了i个,第二行选了j个
第二种方案第一行选了k个,第二行选了i+j-k个
*/
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
const int M = 505 ;
const int mod = 1024523 ;
using namespace std ;
inline int read() {
char c = getchar() ; int x = 0 , w = 1 ;
while(c>'9'||c<'0') { if(c=='-') w = -1 ; c = getchar() ; }
while(c>='0'&&c<='9') { x = x*10+c-'0' ; c = getchar() ; }
return x*w ;
}
int n , m ;
int f[2][M][M] , cur ;
char up[M] , dw[M] ; int main() {
n = read() ; m = read() ;
scanf("%s",up + 1) ; scanf("%s",dw + 1) ;
f[0][0][0] = 1 ;
for(int i = 0 , l ; i <= n ; i ++ , cur ^= 1)
for(int j = 0 ; j <= m ; j ++)
for(int k = 0 ; k <= n ; k ++) {
if(f[cur][j][k] == 0) continue ;
l = i + j - k ;
if(up[i + 1] == up[k + 1])
f[cur ^ 1][j][k + 1] = (f[cur ^ 1][j][k + 1] + f[cur][j][k])%mod ;
if(up[i + 1] == dw[l + 1])
f[cur ^ 1][j][k] = (f[cur ^ 1][j][k] + f[cur][j][k])%mod ;
if(dw[j + 1] == up[k + 1])
f[cur][j + 1][k + 1] = (f[cur][j + 1][k + 1] + f[cur][j][k])%mod ;
if(dw[j + 1] == dw[l + 1])
f[cur][j + 1][k] = (f[cur][j + 1][k] + f[cur][j][k])%mod ;
f[cur][j][k] = 0 ;//卡常技巧,滚动数组时直接清0,避免memset
}
printf("%d\n",f[cur][m][n]) ;
return 0 ;
}

[NOI2009]管道取珠(DP)的更多相关文章

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

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

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

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

  3. bzoj1566: [NOI2009]管道取珠 DP

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=1566 思路 n个球,第i个球颜色为ai,对于颜色j,对答案的贡献为颜色为j的球的个数的平 ...

  4. [NOI2009]管道取珠 DP + 递推

    ---题面--- 思路: 主要难点在思路的转化, 不能看见要求$\sum{a[i]^2}$就想着求a[i], 我们可以对其进行某种意义上的拆分,即a[i]实际上可以代表什么? 假设我们现在有两种取出某 ...

  5. bzoj1566 [NOI2009]管道取珠——DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1566 一眼看上去很懵... 但是答案可以转化成有两个人在同时取珠子,他们取出来一样的方案数: ...

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

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

  7. NOI2009 管道取珠 神仙DP

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

  8. BZOJ 1566 管道取珠(DP)

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

  9. 【题解】NOI2009管道取珠

    又是艰难想题的一晚,又是做不出来的一题 (:д:) 好想哭啊…… 这题最关键的一点还是提供一种全新的想法.看到平方和这种东西,真的不好dp.然而我一直陷在化式子的泥潭中出不来.平方能够联想到什么?原本 ...

  10. BZOJ1566 [NOI2009]管道取珠 【dp】

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

随机推荐

  1. Tiny4412 Linux 内核启动流程

    Linux内核的启动分为压缩内核和非压缩内核两种,这里我们以压缩内核为例.压缩内核运行时,将运行一段解压缩程序,得到真正的内核镜像,然后跳转到内核镜像运行.此时,Linux进入非压缩内核入口,在非压缩 ...

  2. 将字符串str1复制为字符串str2的三种方法

    1.自己编写函数,将两个字符串进行复制 #include<iostream> using namespace std; int main(){ char str1[]="I lo ...

  3. CF 959E Mahmoud and Ehab and the xor-MST

    第一反应是打表找规律……(写了个prim)但是太菜了没找到 于是开始怀疑是不是我的表错了,又写了一个克鲁斯卡尔,然后结果是一样的……(捂脸) 后来从克鲁斯卡尔的算法上发现了一点东西,发现只有2的幂次长 ...

  4. Luogu 3625 [APIO2009]采油区域

    想了很久的dp,看了一眼题解之后感觉自己被安排了. 发现从一个矩形中选择三个不相交的正方形一共只有六种取法. 那么我们可以处理出四个值: $f_{i, j}$分别表示以$(i, j)$为右下角,左下角 ...

  5. MySQL中的时间问题

    MySQL 获得当前日期时间 函数 获得当前日期+时间(date + time)函数:now() mysql> select now(); +---------------------+ | n ...

  6. kaggle House_Price_XGBoost

    kaggle House_Price_final 代码 import numpy as np import pandas as pd from sklearn.ensemble import Rand ...

  7. java全栈day08--面向对象

    今日内容介绍1.面向对象思想2.类与对象的二者关系3.局部变量和成员变量之间的关系4.封装的思想5.private,this关键字的用途6.案例 01面向对象和面向过程的思想 * A: 面向过程与面向 ...

  8. 6678 emif norflash加载

    终于搞定,纪念一下.CCS6很不好用,还是换回CCS5.5吧!

  9. Spring JDBCTemplate配置使用

    一.开发环境 Windows 10 IntelliJ IDEA 2016.1 旗舰版 JDK1.8 二.项目和数据库结构 项目结构: 数据库(MySQL 5.5.39): /* Navicat MyS ...

  10. Java50道经典习题-程序31 数组逆序

    题目:将一个数组逆序输出.分析:用第一个与最后一个交换. public class Prog31 { public static void main(String[] args) { //遍历原始数组 ...