[NOI2009]管道取珠

Description

Luogu1477
BZOJ1566

Solution

这个要将问题转化一下,把求(sum a_i^2)转化为两个人分别取,然后取的一样的方案数,然后就直接上四维DP,然后算出第四维,滚掉第一维就行了。

Code

#include <cstdio>
#include <cstring>
#include <algorithm>

const int N = 510;
const int MOD = 1024523;

int f[2][N][N];
char a[N], b[N];
int la, lb;

void add(int &a, int b) {
	a += b;
	if (a > MOD) a -= MOD;
}

int main() {
	scanf("%d%d", &la, &lb);
	scanf("%s%s", a+1, b+1);
	int p;
	f[0][0][0] = 1, p = 0;
	for (int i = 0; i <= la; ++i, p ^= 1) {
		for (int j = 0; j <= lb; ++j) {
			for (int k = 0; k <= la; ++k) if (f[p][j][k]) {
				int l = i + j - k, tmp = f[p][j][k];
				f[p][j][k] = 0;
				if (l > lb || l < 0) continue;
				if (a[i+1] == a[k+1]) add(f[p^1][j][k+1], tmp);
				if (b[j+1] == a[k+1]) add(f[p][j+1][k+1], tmp);
				if (a[i+1] == b[l+1]) add(f[p^1][j][k], tmp);
				if (b[j+1] == b[l+1]) add(f[p][j+1][k], tmp); 
			}
		}
	}
	printf("%d
", f[p][lb][la]);
	return 0;
}
原文地址:https://www.cnblogs.com/wyxwyx/p/noi2009gdqz.html