[NOI2009]管道区珠

Description

[NOI2009]管道取珠

Solution

对于\(\sum a[i]^2\)
我们不如把它理解成
一个取珠游戏A和一个取珠游戏B同时举行,当A中的任意一个结果和B中的任意一个结果相同时,我们把它加进方案
f[i][j]表示A游戏中上管道取了i个球,B游戏中上管道取了j个球(一个循环枚举k,所以A游戏中下管道取了k-i个球,B游戏中下管道取了k-j个球)
于是便非常的简单了

Code

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define MAXN 610
#define MOD 1024523
int n, m;
int a[MAXN], b[MAXN], f[MAXN][MAXN], c[MAXN][MAXN];
inline int read() {
	int s = 0, w = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
	for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
	return s * w;
}
int main() {
	n = read(), m = read();
	for (register int i = 1; i <= n; i++)
		a[n + 1 - i] = getchar() - 'A';
	getchar();
	for (register int i = 1; i <= m; i++)
		b[m + 1 - i] = getchar() - 'A';
	f[0][0] = 1;
	for (register int k = 1; k <= n + m; k++) {
		for (register int i = max(0, k - m); i <= min(k, n); i++)
			for (register int j = max(0, k - m); j <= min(k, n); j++) {
				c[i][j] = 0;
				if (a[i] == a[j] && i && j)
					(c[i][j] += f[i - 1][j - 1]) %= MOD;
				if (a[i] == b[k - j] && i)
					(c[i][j] += f[i - 1][j]) %= MOD;
				if (b[k - i] == a[j] && j)
					(c[i][j] += f[i][j - 1]) %= MOD;
				if (b[k - i] == b[k - j])
					(c[i][j] += f[i][j]) %= MOD;
			}
		for (register int i = 0; i <= min(k, n); i++)
			for (register int j = 0; j <= min(k, n); j++)
				f[i][j] = c[i][j];
	}
	printf("%d", f[n][n]);
	return 0;
}
posted @ 2019-09-22 20:05  Agakiss  阅读(115)  评论(0编辑  收藏  举报