BZOJ4321queue2——DP/遞推
阿新 • • 發佈:2019-02-18
pan bsp scanf zoj 排列 name d+ 多少 ++
樣例解釋:有兩種方案 2 4 1 3 和 3 1 4 2 遞推方法比較高深,據說與容斥有關:$f_{i}=(i+1)f_{i-1}-(i-2)f_{i-2}-(i-5)f_{i-3}+(i-3)f_{i-4}$
題目描述
n 個沙茶,被編號 1~n。排完隊之後,每個沙茶希望,自己的相鄰的兩 人只要無一個人的編號和自己的編號相差為 1(+1 或-1)就行; 現在想知道,存在多少方案滿足沙茶們如此不苛刻的條件。輸入
只有一行且為用空格隔開的一個正整數 N,其中 100%的數據滿足 1≤N ≤ 1000;輸出
一個非負整數,表示方案數對 7777777 取模。樣例輸入
4樣例輸出
2樣例解釋:有兩種方案 2 4 1 3 和 3 1 4 2 遞推方法比較高深,據說與容斥有關:$f_{i}=(i+1)f_{i-1}-(i-2)f_{i-2}-(i-5)f_{i-3}+(i-3)f_{i-4}$
#include<set> #include<map> #include<queue> #include<stack> #include<cmath> #include<cstdio> #include<bitset> #include<vector> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define mod 7777777 using namespace std; int n; ll f[1010]; int main() { scanf("%d",&n); f[0]=f[1]=1ll; f[2]=f[3]=0ll; for(int i=4;i<=n;i++) { f[i]=1ll*f[i-1]*(i+1)%mod-1ll*f[i-2]*(i-2)%mod-1ll*f[i-3]*(i-5)%mod+1ll*f[i-4]*(i-3)%mod; f[i]=(f[i]%mod+mod)%mod; } printf("%lld",f[n]); }
$DP$做法:考慮對於前$i$個數的排列,當加入$i+1$時對排列的影響,設$f[i][j]/g[i][j]$分別表示前$i$個數的排列中有$j$對相差為$1$的數相鄰(後文稱為不合法數對)且$i$兩邊有/沒有與它相差為1的的數。
考慮這兩個方程如何轉移,對於$f[i][j]$,加入$i+1$:
1、與$i$相鄰且增加一對不合法數對,有一種放法,可轉移到$f[i+1][j+1]$
2、與$i$相鄰且不合法數對數不變,有一種放法,可轉移到$f[i+1][j]$
3、與$i$不相鄰且減少一對不合法數對,有$(j-1)$種放法,可轉移到$g[i+1][j-1]$
4、與$i$不相鄰且不合法數對數不變,有$(i-j)$種放法,可轉移到$g[i+1][j]$
對於$g[i][j]$,加入$i+1$:
1、與$i$相鄰且增加一對不合法數對,有兩種放法,可轉移到$f[i+1][j+1]$
2、與$i$不相鄰且減少一對不合法數對,有$j$種放法,可轉移到$g[i+1][j-1]$
3、與$i$不相鄰且不合法數對數不變,有$(i-j-1)$種放法,可轉移到$g[i+1][j]$
#include<set> #include<map> #include<queue> #include<stack> #include<cmath> #include<cstdio> #include<bitset> #include<vector> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define mod 7777777 using namespace std; int n; ll f[1010][1010]; ll g[1010][1010]; int main() { scanf("%d",&n); g[1][0]=1; for(int i=1;i<n;i++) { for(int j=0;j<i;j++) { (f[i+1][j+1]+=f[i][j])%=mod; (f[i+1][j]+=f[i][j])%=mod; (g[i+1][j-1]+=1ll*(j-1)*f[i][j])%=mod; (g[i+1][j]+=1ll*(i-j)*f[i][j])%=mod; (f[i+1][j+1]+=2*g[i][j])%=mod; (g[i+1][j-1]+=1ll*j*g[i][j])%=mod; (g[i+1][j]+=1ll*(i-j-1)*g[i][j])%=mod; } } printf("%lld",g[n][0]); }
BZOJ4321queue2——DP/遞推