[BZ1925] [SDOI2010] Goblin tribes

[BZ1925] [SDOI2010] Goblin tribes

Portal

DP a very interesting question.

We found that because it is difficult to consider the number of each permutation of whether to use, so I think we just maintain the relative relationship.

When we consider a new location, the number assigned to a new position of ranking (can be understood as the size of this position is inserted in the middle of the size of the original two locations).

So order \ (dp [i] [j ] [0/1] \) represents the number before i, the number i is the i-th ranked front j, the last two numbers are opposing relationship when the rising / falling the number of programs.

Then there is:
\ [DP [I] [J] [0] = \ sum_ K = {}. 1. 1} ^ {J-DP [. 1-I] [K] [. 1] \\ DP [I] [J] [1] = \ sum_ {k = j} ^ {i-1} dp [i-1] [k] [0] \\ dp [1] [1] [1] = dp [1] [1] [ 0] = 1; \]
then click prefix and optimization:
\ [F [I] [J] [0] = \ sum_ K = {1} ^ {J} DP [I] [J] [0] \\ F [i] [j] [1
] = \ sum_ {k = 1} ^ {j} dp [i] [j] [1] \\ \] then transfer is:
\ [DP [I] [J] [0 ] = f [i-1] [j-1] [1] \\ dp [i] [j] [1] = f [i-1] [i-1] [0] -f [i-1] [j-1] [0] \\ initialization: f [1] [1]
[0] = f [1] [1] [1] = 1 \] Code:

#include<iostream>
#include<cstdio>
#include<algorithm>
const int maxn=4500;
using namespace std;
int n,p;
int dp[2][maxn][2],f[2][maxn][2];
int main() {
    scanf("%d%d",&n,&p);
    dp[1][1][0]=dp[1][1][1]=f[1][1][1]=f[1][1][0]=1;
    for(int i=2;i<=n;i++) {
        int md=i&1;
        for(int j=1;j<=i;j++)dp[md][j][0]=dp[md][j][1]=0;
        for(int j=1;j<=i;j++) {
            dp[md][j][0]+=f[md^1][j-1][1];dp[md][j][0]%=p;
            dp[md][j][1]+=f[md^1][i-1][0]-f[md^1][j-1][0];dp[md][j][1]%=p;
        }
        for(int j=1;j<=i;j++) {
            f[md][j][0]=f[md][j-1][0]+dp[md][j][0];f[md][j][0]%=p;
            f[md][j][1]=f[md][j-1][1]+dp[md][j][1];f[md][j][1]%=p;
        }
    }
    printf("%d",(((f[n&1][n][1]+f[n&1][n][0])%p)+p)%p);
}

Guess you like

Origin www.cnblogs.com/GavinZheng/p/11620731.html