fi,j,k 表示由前 i 个人组成,有 j 对人是相邻的, i 与 i−1 是否相邻
DP的话直接分类讨论转移就行了
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;
const int N=1010,P=7777777;
int n;
int f[N][N][2];
inline void add(int &x,int y){
(x+=y)%=P;
}
int main(){
scanf("%d",&n);
if(n==1) return puts("1"),0;
if(n==2) return puts("0"),0;
f[2][1][1]=2;
for(int i=2;i<n;i++)
for(int j=0;j<i;j++){
add(f[i+1][j+1][1],2*f[i][j][0]+f[i][j][1]);
add(f[i+1][j][1],f[i][j][1]);
add(f[i+1][j][0],1LL*f[i][j][1]*(i-j)%P);
add(f[i+1][j][0],1LL*f[i][j][0]*(i-j-1)%P);
if(j) add(f[i+1][j-1][0],1LL*f[i][j][0]*j%P+1LL*f[i][j][1]*(j-1)%P);
}
printf("%d\n",f[n][0][0]);
return 0;
}
本文介绍了一种使用动态规划解决特定排列问题的方法,通过分类讨论实现状态转移,最终求得给定人数条件下,无相邻人对的排列方案数量。

703

被折叠的 条评论
为什么被折叠?



