zoukankan      html  css  js  c++  java
  • [BZOJ1566][NOI2009]管道取珠

    [BZOJ1566][NOI2009]管道取珠

    试题描述

     

    输入

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

    输出

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

    输入示例

    2 1
    AB
    B

    输出示例

    5

    数据规模及约定

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

    题解

    这题思路比较妙,我们需要先想想 ∑ai2 有什么意义。如果我们构造出这样一个游戏场景,即两个人同时玩两份同样的如题目所述的管道取珠的游戏,那么这两个人游戏结束后取到的珠子颜色序列一模一样的方案数就是题目里要求的答案。

    令这两个人分别是 p1 和 p2。于是设 f[i][j][k] 表示 p1 取了第二个管道中的前 i 个珠子,第一个管道中的前 j 个珠子;p2 取了第一个管道的前 k 个珠子,这个状态下颜色序列相同的方案数,转移显然。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <algorithm>
    using namespace std;
    
    int read() {
    	int x = 0, f = 1; char c = getchar();
    	while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
    	while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
    	return x * f;
    }
    
    #define maxn 510
    #define MOD 1024523
    int n, m, f[2][maxn][maxn];
    bool has[2][maxn][maxn];
    char A[maxn], B[maxn];
    
    int main() {
    	n = read(); m = read();
    	scanf("%s%s", A + 1, B + 1);
    	
    	int cur = 0;
    	f[0][0][0] = 1; has[0][0][0] = 1;
    	for(int i = 0; i <= m; i++, cur ^= 1) {
    		for(int j = 0; j <= n; j++)
    			for(int k = 0; k <= n; k++) f[cur^1][j][k] = has[cur^1][j][k] = 0;
    		for(int j = 0; j <= n; j++)
    			for(int k = 0; k <= n; k++) if(has[cur][j][k]) {
    //				printf("%d %d %d: %d
    ", i, j, k, f[cur][j][k]);
    				int bj = i, bk = i + j - k;
    				if(j < n && k < n && A[j+1] == A[k+1]) {
    					f[cur][j+1][k+1] += f[cur][j][k]; has[cur][j+1][k+1] = 1;
    					if(f[cur][j+1][k+1] >= MOD) f[cur][j+1][k+1] -= MOD;
    				}
    				if(j < n && bk < m && A[j+1] == B[bk+1]) {
    					f[cur][j+1][k] += f[cur][j][k]; has[cur][j+1][k] = 1;
    					if(f[cur][j+1][k] >= MOD) f[cur][j+1][k] -= MOD;
    				}
    				if(bj < m && k < n && B[bj+1] == A[k+1]) {
    					f[cur^1][j][k+1] += f[cur][j][k]; has[cur^1][j][k+1] = 1;
    					if(f[cur^1][j][k+1] >= MOD) f[cur^1][j][k+1] -= MOD;
    				}
    				if(bj < m && bk < m && B[bj+1] == B[bk+1]) {
    					f[cur^1][j][k] += f[cur][j][k]; has[cur^1][j][k] = 1;
    					if(f[cur^1][j][k] >= MOD) f[cur^1][j][k] -= MOD;
    				}
    			}
    	}
    	
    	printf("%d
    ", f[cur^1][n][n]);
    	
    	return 0;
    }
    
  • 相关阅读:
    实验一、拿下WordPress网站
    特殊问题讨论
    BGP基础配置
    《快活帮》第七次作业:团队项目设计完善&编码
    《快活帮》第六次作业:团队项目系统设计改进与详细设计
    《快活帮》第五次作业:项目需求分析改进与系统设计
    《快活帮》第四次作业:项目需求调研与分析
    《快活帮》第三次作业:团队项目的原型设计
    《快活帮》第二次作业:团队项目选题报告
    《快活帮》第一次作业:团队亮相
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/6402793.html
Copyright © 2011-2022 走看看