1. 程式人生 > >Codeforces 869C The Intriguing Obsession:組合數 or dp

Codeforces 869C The Intriguing Obsession:組合數 or dp

max 不同的 div get () 題目 namespace pro string

題目鏈接:http://codeforces.com/problemset/problem/869/C

題意:

  紅色、藍色、紫色的小島分別有a,b,c個。

  你可以在兩個不同的島之間架橋,橋的長度為1。

  任意兩個顏色相同的島之間的距離不能小於3。

  問你合法的架橋方案數。

題解:

  顯然只能在不同顏色的島之間連邊。

  而且一個島對於一種顏色,最多只能連一個島。

  設f(x,y)表示兩種顏色的島相互連邊,分別有x,y個,連邊的方案數。(x < y)

  那麽ans = f(a,b) * f(b,c) * f(a,c)

  解法1(組合數):

    枚舉共連了k條邊,k∈[1,x]。

    那麽連了k條邊的方案數 = C(x,k) * C(y,k) * k!

    總方案數f(x,y) = ∑(C(x,k) * C(y,k) * k!)

  解法2(dp):

    向其中A集合中加入一個島,要麽不連邊,要麽根B集合中的任意一個點連邊(共j種方案)。

    f(i,j) = f(i-1,j) + f(i-1,j-1)*j

AC Code(combination):

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string
.h> 4 #define MAX_N 5005 5 #define MOD 998244353 6 7 using namespace std; 8 9 int mx=0; 10 int a[3]; 11 long long f[MAX_N]; 12 long long c[MAX_N][MAX_N]; 13 long long ans=1; 14 15 void cal_f() 16 { 17 f[0]=1; 18 for(int i=1;i<=mx;i++) f[i]=f[i-1]*i%MOD; 19 } 20 21
void cal_c() 22 { 23 c[0][0]=1; 24 for(int i=1;i<=mx;i++) 25 { 26 c[i][0]=1; 27 for(int j=1;j<=i;j++) 28 { 29 c[i][j]=(c[i-1][j-1]+c[i-1][j])%MOD; 30 } 31 } 32 } 33 34 int main() 35 { 36 for(int i=0;i<3;i++) 37 { 38 cin>>a[i]; 39 mx=max(mx,a[i]); 40 } 41 cal_f(); 42 cal_c(); 43 for(int i=0;i<3;i++) 44 { 45 for(int j=i+1;j<3;j++) 46 { 47 int x=min(a[i],a[j]); 48 int y=max(a[i],a[j]); 49 int sum=0; 50 for(int k=0;k<=x;k++) 51 { 52 sum=(sum+c[x][k]*c[y][k]%MOD*f[k])%MOD; 53 } 54 ans=ans*sum%MOD; 55 } 56 } 57 cout<<ans<<endl; 58 }

AC Code(dp):

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #define MAX_N 5005
 5 #define MOD 998244353
 6 
 7 using namespace std;
 8 
 9 int a,b,c;
10 long long dp[MAX_N][MAX_N];
11 
12 int main()
13 {
14     cin>>a>>b>>c;
15     int mx=max(a,max(b,c));
16     for(int i=0;i<=mx;i++)
17     {
18         dp[i][0]=dp[0][i]=1;
19     }
20     for(int i=1;i<=mx;i++)
21     {
22         for(int j=1;j<=mx;j++)
23         {
24             dp[i][j]=(dp[i-1][j]+dp[i-1][j-1]*j)%MOD;
25         }
26     }
27     cout<<dp[a][b]*dp[b][c]%MOD*dp[a][c]%MOD<<endl;
28 }

Codeforces 869C The Intriguing Obsession:組合數 or dp