bzoj1566 [NOI2009]管道取珠

Posted 逢山开路 遇水架桥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj1566 [NOI2009]管道取珠相关的知识,希望对你有一定的参考价值。

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1566

【题解】

考虑表示的实际意义,相当于我取两次球,得到方案完全相同的个数。

设$f_{i,j,k}$表示取了$i$个,第一种上面取$j$个,第二种上面取$k$个,随便转移。

复杂度$O(n^3)$。

技术分享
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 5e2 + 10;
const int mod = 1024523;

int f[2][M][M];

int nA, nB;
char a[M], b[M];

inline void cadd(int &a, int b) {
    a += b;
    if(a >= mod) a -= mod;
}

int main() {
    cin >> nA >> nB;
    scanf("%s%s", a+1, b+1);
    reverse(a+1, a+nA+1);
    reverse(b+1, b+nB+1);
    int cur = 0, nxt = 1;
    f[cur][0][0] = 1;
    for (int i=0; i<nA+nB; ++i) {
        int end_num = min(nA, i);
        memset(f[nxt], 0, sizeof f[nxt]);
        for (int j=0, jj; j<=end_num; ++j)
            for (int k=0, kk; k<=end_num; ++k) 
                if(f[cur][j][k]) {
                    jj = i - j, kk = i - k;
                    if(jj > nB || kk > nB) continue;
                    if(a[j+1] == a[k+1]) cadd(f[nxt][j+1][k+1], f[cur][j][k]);
                    if(b[jj+1] == a[k+1]) cadd(f[nxt][j][k+1], f[cur][j][k]);
                    if(a[j+1] == b[kk+1]) cadd(f[nxt][j+1][k], f[cur][j][k]);
                    if(b[jj+1] == b[kk+1]) cadd(f[nxt][j][k], f[cur][j][k]);
                }
        swap(cur, nxt);
    }
    cout << f[cur][nA][nA];
    return 0;
}
View Code

 

以上是关于bzoj1566 [NOI2009]管道取珠的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1566 [NOI2009]管道取珠

bzoj1566Noi2009管道取珠

BZOJ1566 NOI2009管道取珠

BZOJ 1566 管道取珠(DP)

BZOJ 1566 管道取珠

LuoguP1758 [NOI2009] 管道取珠