Pipe bead extraction (NOI2009, linear DP)

1. Topic link

\quad Pipe bead extraction

2. The main idea of ​​the topic

\quad The original questions are excellent.
Insert picture description here

Three. Analysis

\quad This question is a wonderful one-hand conversion, I learned it~~

\quad In the problem, let a[i] be a certain number of solutions in the final sequence, but let us solve a [i] 2 a[i]^2a[i]2. Obviously we need to find out the relationship between the two.

\quad Assuming that we have two identical and independent systems, and two people are operating at the same time, it is not difficult to prove that for a certain final sequence F, the number of solutions obtained by the two people after the operation is the same as F is a [i] 2 a[i]^2a[i]2

\quad After this step of transformation, we can happily dp spicy~~ (but goose is not...)

\quad Let dp[i][j][k][l] be the first person taking i balls from pipe one, the first person taking j balls from pipe two, and the second person taking j balls from pipe one k balls, the second person took l balls from pipe two, and the number of schemes with the same sequence currently constituted.

\quad But, such a state means that time and space will burst. Since the two sequences are the same, then i + j == k + l, so we can omit one dimension, in addition to rolling optimization on the first dimension, it will be stuck Enter the time and space of AC!

\quad The state transition equation is

if(s[i + 1] == s[k + 1]) f[p^1][j][k + 1] = (f[p^1][j][k + 1] + f[p][j][k]) % mod;
if(s[i + 1] == t[l + 1]) f[p^1][j][k] = (f[p^1][j][k] + f[p][j][k]) % mod;
if(t[j + 1] == s[k + 1]) f[p][j + 1][k + 1] = (f[p][j + 1][k + 1] + f[p][j][k]) % mod;
if(t[j + 1] == t[l + 1]) f[p][j + 1][k] = (f[p][j + 1][k] + f[p][j][k]) % mod;

In addition, you can add a little optimization, just like the sample paper below

if(!f[p][j][k])    continue;
if(s[i + 1] == s[k + 1]) f[p^1][j][k + 1] = (f[p^1][j][k + 1] + f[p][j][k]) % mod;
if(s[i + 1] == t[l + 1]) f[p^1][j][k] = (f[p^1][j][k] + f[p][j][k]) % mod;
if(t[j + 1] == s[k + 1]) f[p][j + 1][k + 1] = (f[p][j + 1][k + 1] + f[p][j][k]) % mod;
if(t[j + 1] == t[l + 1]) f[p][j + 1][k] = (f[p][j + 1][k] + f[p][j][k]) % mod;

\quad After testing, the time limit has been optimized a lot! ! !
Insert picture description here

Four. Code implementation

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const int M = (int)5e2;
const ll mod = (ll)1024523;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;

int n, m;
char s[M + 5], t[M + 5];
int f[2][M + 5][M + 5];

int main()
{
    
    
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
    scanf("%d %d", &n, &m);
    scanf("%s %s", s + 1, t + 1);
    reverse(s + 1, s + n + 1); reverse(t + 1, t + m + 1);
    f[0][0][0] = 1;
    for(int i = 0, p = 0; i <= n; ++i, p ^= 1)
    {
    
    
        for(int j = 0; j <= m; ++j)
        {
    
    
            for(int k = 0; k <= n; ++k)
            {
    
    
                int l = i + j - k;
                if(l < 0 || l > m) continue;
                if(!f[p][j][k])    continue;
                if(s[i + 1] == s[k + 1]) f[p^1][j][k + 1] = (f[p^1][j][k + 1] + f[p][j][k]) % mod;
                if(s[i + 1] == t[l + 1]) f[p^1][j][k] = (f[p^1][j][k] + f[p][j][k]) % mod;
                if(t[j + 1] == s[k + 1]) f[p][j + 1][k + 1] = (f[p][j + 1][k + 1] + f[p][j][k]) % mod;
                if(t[j + 1] == t[l + 1]) f[p][j + 1][k] = (f[p][j + 1][k] + f[p][j][k]) % mod;
                f[p][j][k] = 0;
            }
        }
    }
    printf("%d\n", f[(n + 1) & 1][m][n]);
    return 0;
}

Guess you like

Origin blog.csdn.net/The___Flash/article/details/106413451