C.Positions in Permutations
题意:若 ∣ p [ i ] − i ∣ = 1 |p[i]-i|=1 ∣p[i]−i∣=1,则这是一个完美位置。问 n n n个位置恰好有 k k k个完美位置的方案数。
设
F
(
m
)
F(m)
F(m)代表固定
m
m
m个完美位置,
G
(
m
)
G(m)
G(m)代表恰好有
m
m
m个完美位置。
∑
i
=
0
n
(
−
1
)
i
(
n
i
)
=
0
=
[
n
=
0
]
\sum_{i=0}^n(-1)^i\tbinom{n}{i}=0=[n=0]
∑i=0n(−1)i(in)=0=[n=0]
F ( m ) = ∑ i = m n ( i m ) G ( i ) F(m)=\sum_{i=m}^n\tbinom{i}{m}G(i) F(m)=∑i=mn(mi)G(i)
G
(
m
)
=
∑
i
=
m
n
(
i
m
)
G
(
i
)
[
i
−
m
=
0
]
G(m)=\sum_{i=m}^n\tbinom{i}{m}G(i)[i-m=0]
G(m)=∑i=mn(mi)G(i)[i−m=0]
=
∑
i
=
m
n
(
i
m
)
G
(
i
)
∑
j
=
0
i
−
m
(
−
1
)
j
(
i
−
m
j
)
=\sum_{i=m}^n\tbinom{i}{m}G(i)\sum_{j=0}^{i-m}(-1)^{j}\tbinom{i-m}j
=∑i=mn(mi)G(i)∑j=0i−m(−1)j(ji−m)
=
∑
i
=
m
n
(
i
m
)
G
(
i
)
∑
j
=
m
i
(
−
1
)
j
−
m
(
i
−
m
j
−
m
)
=\sum_{i=m}^n\tbinom{i}{m}G(i)\sum_{j=m}^i(-1)^{j-m}\tbinom{i-m}{j-m}
=∑i=mn(mi)G(i)∑j=mi(−1)j−m(j−mi−m)
=
∑
j
=
m
n
(
−
1
)
j
−
m
(
j
m
)
∑
i
=
j
m
(
i
j
)
G
(
i
)
=\sum_{j=m}^n(-1)^{j-m}\tbinom{j}{m}\sum_{i=j}^m\tbinom{i}{j}G(i)
=∑j=mn(−1)j−m(mj)∑i=jm(ji)G(i)
=
∑
j
=
m
n
(
−
1
)
j
−
m
(
j
m
)
F
(
j
)
=\sum_{j=m}^n(-1)^{j-m}\tbinom{j}mF(j)
=∑j=mn(−1)j−m(mj)F(j)
设 d p [ i ] [ j ] [ 0 / 1 ] [ 0 / 1 ] 设dp[i][j][0/1][0/1] 设dp[i][j][0/1][0/1] i 代表前 i 个位置, j 代表有 j 个完美位置,第一个 0 / 1 代表第 i 个位置有没有被使用,第二个代表第 i + 1 个位置 i代表前i个位置,j代表有j个完美位置,第一个0/1代表第i个位置有没有被使用,第二个代表第i+1个位置 i代表前i个位置,j代表有j个完美位置,第一个0/1代表第i个位置有没有被使用,第二个代表第i+1个位置
d
p
[
i
]
[
j
]
[
0
]
[
0
]
=
d
p
[
i
−
1
]
[
j
−
1
]
[
0
]
[
0
]
+
d
p
[
i
−
1
]
[
j
]
[
0
]
[
0
]
+
d
p
[
i
−
1
]
[
j
]
[
1
]
[
0
]
dp[i][j][0][0]=dp[i-1][j-1][0][0]+dp[i-1][j][0][0]+dp[i-1][j][1][0]
dp[i][j][0][0]=dp[i−1][j−1][0][0]+dp[i−1][j][0][0]+dp[i−1][j][1][0]
d
p
[
i
]
[
j
]
[
0
]
[
1
]
=
d
p
[
i
−
1
]
[
j
−
1
]
[
0
]
[
0
]
+
d
p
[
i
−
1
]
[
j
−
1
]
[
1
]
[
0
]
dp[i][j][0][1]=dp[i-1][j-1][0][0]+dp[i-1][j-1][1][0]
dp[i][j][0][1]=dp[i−1][j−1][0][0]+dp[i−1][j−1][1][0]
d
p
[
i
]
[
j
]
[
1
]
[
0
]
=
d
p
[
i
−
1
]
[
j
−
1
]
[
0
]
[
1
]
+
d
p
[
i
−
1
]
[
j
]
[
0
]
[
1
]
+
d
p
[
i
−
1
]
[
j
]
[
1
]
[
1
]
dp[i][j][1][0]=dp[i-1][j-1][0][1]+dp[i-1][j][0][1]+dp[i-1][j][1][1]
dp[i][j][1][0]=dp[i−1][j−1][0][1]+dp[i−1][j][0][1]+dp[i−1][j][1][1]
d
p
[
i
]
[
j
]
[
1
]
[
1
]
=
d
p
[
i
−
1
]
[
j
−
1
]
[
0
]
[
1
]
+
d
p
[
i
−
1
]
[
j
−
1
]
[
1
]
[
1
]
dp[i][j][1][1]=dp[i-1][j-1][0][1]+dp[i-1][j-1][1][1]
dp[i][j][1][1]=dp[i−1][j−1][0][1]+dp[i−1][j−1][1][1]
F ( i ) = ( d p [ n ] [ i ] [ 0 ] [ 0 ] + d p [ n ] [ i ] [ 1 ] [ 0 ] ) ∗ ( n − i ) ! F(i)=(dp[n][i][0][0]+dp[n][i][1][0])*(n-i)! F(i)=(dp[n][i][0][0]+dp[n][i][1][0])∗(n−i)!
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <map>
#include <string>
#include <stack>
#include <cctype>
#include <vector>
#include <queue>
#include <set>
#include <utility>
#include <cassert>
using namespace std;
#define ll long long
#define maxn 500500
#define mod 1000000007
#define MOD 998244353
#define eps 1e-10
const ll inf = 0x3f3f3f3f3f3f3f3f;
const ll INF = 0x3f3f3f3f;
const ll mod1=1e9+7;
const ll mod2=1e9+9;
template <typename T>
inline void read(T& X) {X = 0; int w = 0; char ch = 0;while (!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }while (isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();if (w) X = -X;}
char F[200];inline void write(int x){if(x == 0){putchar('0');return;}int tmp = x > 0 ? x : -x;int cnt = 0;if(x < 0)putchar( '-' );while(tmp > 0){F[cnt++] = tmp % 10 + '0';tmp /= 10;}while(cnt > 0)putchar(F[--cnt]) ;}
template<typename T> void print(T x){if(x>9) print(x/10);putchar(x%10+'0');}
ll dp[1010][1010][2][2];
ll f[1010];
ll a[2022];
ll c[2022];
ll q_pow(ll x,ll y){
ll ans=1;
while(y){
if(y%2){
y--;
ans=ans*x%mod;
}
else{
y/=2;
x=x*x%mod;
}
}
return ans%mod;
}
void init(){
a[1]=1;c[1]=1;a[0]=1;c[0]=1;
for(int i=2;i<=1000;i++)a[i]=a[i-1]*i%mod,c[i]=q_pow(a[i],mod-2);
}
ll C(int n,int m){
if(n<m)return 0ll;
return a[n]*c[m]%mod*c[n-m]%mod;
}
int main()
{
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int n,m;
read(n);read(m);
init();
dp[1][0][0][0]=dp[1][1][0][1]=1ll;
for(int i=2;i<=n;i++){
dp[i][0][0][0]=1ll;
for(int j=1;j<=i;j++){
dp[i][j][0][0]=(dp[i-1][j-1][0][0]+dp[i-1][j][0][0]+dp[i-1][j][1][0])%mod;
dp[i][j][0][1]=(dp[i-1][j-1][0][0]+dp[i-1][j-1][1][0])%mod;
dp[i][j][1][0]=(dp[i-1][j-1][0][1]+dp[i-1][j][0][1]+dp[i-1][j][1][1])%mod;
dp[i][j][1][1]=(dp[i-1][j-1][1][1]+dp[i-1][j-1][0][1])%mod;
}
}
for(int i=0;i<=n;i++)f[i]=(dp[n][i][0][0]+dp[n][i][1][0])%mod*a[n-i]%mod;
ll ans=0;
for(int i=m;i<=n;i++){
ll res=f[i]*C(i,m)%mod;
if((i-m)%2)ans=ans+(mod-res);
else ans=ans+res;
ans%=mod;
}
cout<<ans;
return 0;
}