1. 程式人生 > >數論--二項式反演

數論--二項式反演

code idt std .com -- img wid while height

技術分享

若能湊出其中一個式子,則能反演出另外一個式子

應用:

HDU 1465

設g(i)表示正好有i封信裝錯信封

那麽全部的C(n, i)*g(i)加起來正好就是所有裝信的情況,總共n!(全排列)種情況

即:

技術分享

代碼:

 1 #include<cstdio>
 2 #include<iostream>
 3 using namespace std;
 4 typedef long long LL;
 5 LL fac[30];
 6 LL ans[30];
 7 LL c[30][30];
 8 int p[30];
 9 
10 void init()
11 {
12     c[1
][0]=1; 13 c[1][1]=1; 14 p[0]=1; 15 p[1]=-1; 16 for(int i=2;i<=20;i++) 17 { 18 p[i]=p[i-1]*(-1); 19 20 for(int j=0;j<=i;j++) 21 { 22 if(j==0||j==i) 23 c[i][j]=1; 24 else 25 c[i][j]=c[i-1][j-1]+c[i-1][j];
26 } 27 } 28 29 } 30 31 int main() 32 { 33 init(); 34 fac[0]=1; 35 fac[1]=1; 36 for(int i=2;i<=20;i++) 37 fac[i]=i*fac[i-1]; 38 for(int i=1;i<=20;i++) 39 { 40 ans[i]=0; 41 for(int j=0;j<=i;j++) 42 { 43 ans[i]+=fac[j]*p[i-j]*c[i][j];
44 } 45 } 46 47 int n; 48 while(scanf("%d",&n)!=EOF) 49 { 50 printf("%I64d\n",ans[n]); 51 } 52 }

數論--二項式反演