Given N, K, the number of queries is arranged. Yes | P [I]-I | = 1 is K.
Solution
Direct DP has great aftereffects.
Therefore, we want to fix K numbers so that they are valid. Therefore, we set DP [I] [J] [0/1] [0/1] to indicate the number of I before, and enter the number of J, whether or not the current position is selected, and whether or not the next position is selected. In this case, the transfer is relatively simple.
In this case, the number of J is removed, and the remaining number is randomly entered. The multiplication is arranged in full.
But this will calculate more.
Then there is a denial-of-service model to solve this problem.
#include<iostream>#include<cstdio>#define N 1002using namespace std;typedef long long ll;int n,k;ll dp[N][N][2][2],jie[N],ni[N],g[N],ans;const int mod=1e9+7;ll calc(int n,int m){ return jie[n]*ni[m]%mod*ni[n-m]%mod;}ll power(ll x,int y){ ll ans=1; while(y){ if(y&1)(ans*=x)%=mod; (x*=x)%=mod; y>>=1; } return ans;}int main(){ scanf("%d%d",&n,&k);jie[0]=1; for(int i=1;i<=n;++i)jie[i]=(jie[i-1]*i)%mod;ni[n]=power(jie[n],mod-2); for(int i=n-1;i>=0;--i)ni[i]=ni[i+1]*(i+1)%mod; dp[0][0][1][0]=1; for(int i=1;i<=n;++i){ for(int j=0;j<=n;++j){ dp[i][j][0][0]=(dp[i-1][j][0][0]+dp[i-1][j][1][0])%mod; dp[i][j][1][0]=(dp[i-1][j][0][1]+dp[i-1][j][1][1])%mod; if(j){ (dp[i][j][0][0]+=dp[i-1][j-1][0][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][0][1]%=mod; (dp[i][j][1][0]+=dp[i-1][j-1][0][1])%=mod; dp[i][j][1][1]+=(dp[i-1][j-1][0][1]+dp[i-1][j-1][1][1])%mod; dp[i][j][1][1]%=mod; } } } for(int i=k;i<=n;++i) g[i]=(dp[n][i][0][0]+dp[n][i][1][0])%mod*jie[n-i]%mod; for(int i=k;i<=n;++i)(ans+=(((i-k)&1)?-1:1)*calc(i,k)*g[i]%mod+mod)%=mod; ans=(ans+mod)%mod; cout<<ans; return 0;}
Cf285e positions in permutations (DP + rejection)