题解:AT_abc282_g [ABC282G] Similar Permutation
Similar Permutation
观察题面,这是一道有关排列计数的问题。而对于排列问题,可以按照位置或值的具体值或相对值来 dp。而此题需要知道相邻位置两项的大小关系,则可以对每一个位置依次考虑其值在序列中的排名,即其相对的值。假设当前 dp 到位置
#define L(i, j, k) for (int i=(j); i<=(k); ++i)
const int N=110;
int n, kn, mod, dp[N][N][N][N];
signed main() {
rd(n, kn, mod);
dp[1][1][1][0]=1;
L(i, 2, n) {
L(j, 1, i) L(k, 1, i) L(l, 0, i-1) {
if (l) dp[i][j][k][l]=((ll)dp[i][j][k][l]+dp[i-1][j-1][k-1][l-1]+dp[i-1][i-1][i-1][l-1]-dp[i-1][j-1][i-1][l-1]-dp[i-1][i-1][k-1][l-1]+dp[i-1][j-1][k-1][l-1])%mod;
dp[i][j][k][l]=((ll)dp[i][j][k][l]+dp[i-1][j-1][i-1][l]-dp[i-1][j-1][k-1][l]+dp[i-1][i-1][k-1][l]-dp[i-1][j-1][k-1][l])%mod;
}
L(j, 1, i) L(k, 1, i) L(l, 0, i-1) dp[i][j][k][l]=(dp[i][j][k][l]+dp[i][j][k-1][l])%mod;
L(j, 1, i) L(k, 1, i) L(l, 0, i-1) dp[i][j][k][l]=(dp[i][j][k][l]+dp[i][j-1][k][l])%mod;
}
printf("%d\n", (dp[n][n][n][kn]+mod)%mod);
return 0;
}