標籤:des style blog http io color ar os sp
轉載請註明出處: http://www.cnblogs.com/fraud/ ——by fraud
Series-Parallel Networks
Input: standard input
Output: standard output
Time Limit: 5 seconds
Memory Limit: 32 MB
In this problem you are expected to count two-terminal series-parallel networks. These are electric networks considered topologically or geometrically, that is, without the electrical properties of the elements connected. One of the two terminals can be considered as the source and the other as the sink.
A two-terminal network will be considered series-parallel if it can be obtained iteratively in the following way:
q A single edge is two-terminal series-parallel.
q If G1 and G2 are two-terminal series-parallel, so is the network obtained by identifying the sources and sinks, respectively (parallel composition).
q If G1 and G2 are two-terminal series-parallel, so is the network obtained by identifying the sink of G1with the source of G2 (series composition).
Note here that in a series-parallel network two nodes can be connected by multiple edges. Moreover, networks are regarded as equivalent, not only topologically, but also when interchange of elements in series brings them into congruence; otherwise stated, series interchange is an equivalence operation. For example, the following three networks are equivalent:
Similarly, parallel interchange is also an equivalence operation. For example, the following three networks are also equivalent:
Now, given a number N, you are expected to count the number of two-terminal series parallel networks containing exactly N edges. For example, for N = 4, there are exactly 10 series-parallel networks as shown below:
Input
Each line of the input file contains an integer N (1 £N£ 30) specifying the number of edges in the network.
A line containing a zero for N terminates the input and this input need not be considered.
Output
For each N in the input file print a line containing the number of two-terminal series-parallel networks that can be obtained using exactly N edges.
Sample Input
1
4
15
0
Sample Output
1
10
1399068
(World Final Warm-up Contest, Problem Setter: Rezaul Alam Chowdhury)
這道題目想了好久,最終還是參考了題解。
大致意思就是給你n條邊,問你恰好用n條邊,能構成幾種串並連網絡。(串聯的各個部分可以任意調換,並聯在一起的各個部分也可以任意調換,若通過調換可得,則二者視為等效)
分析:將每個網路都看成一棵樹,為每次串聯或者並聯建立一個結點,並且把串聯/並聯部分看作該結點的子樹,則可以轉化為樹形dp。
dp[i][j]表示每棵子樹葉子數目不超過i,一共有j片葉子的方案數。
f[i]=dp[i-1][i],則根據可重複的群組合的公式,在有k個恰好包含i片葉子的子樹時,其方案數等於C(f[i]+k-1,k);
dp[i][j]=∑(C(f[i]+k-1,k)*d[i-1][j-p*i]) k≥0,k*i<=j
另外注意處理好邊界。
對於求這個組合數,想不出較好的方法,最終還是採用了劉汝佳在大白書上寫的用double來做的方法(雖然我一度擔心會因為double的精度問題會使得有所誤差)。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 typedef long long ll; 6 ll dp[110][110]; 7 ll f[110]; 8 ll C(ll n,int m) 9 {10 double ret=1;11 for(ll i=n+1-m;i<=n;i++)12 {13 ret*=i;14 }15 for(int i=1;i<=m;i++)ret/=i;16 return (ll)(ret+0.5);17 }18 int main()19 {20 ios::sync_with_stdio(false);21 int n=30;22 f[1]=1;23 for(int i=1;i<=n;i++){dp[0][i]=0;dp[i][1]=1;}24 for(int i=0;i<=n;i++)dp[i][0]=1;25 for(int i=1;i<=n;i++)26 {27 for(int j=2;j<=n;j++)28 {29 dp[i][j]=0;30 for(int k=0;i*k<=j;k++)31 {32 dp[i][j]+=C(f[i]+k-1,k)*dp[i-1][j-i*k];33 }34 }35 f[i+1]=dp[i][i+1];36 }37 for(int i=2;i<=n;i++)f[i]*=2LL;38 while(cin>>n&&n)39 {40 cout<<f[n]<<endl;41 }42 }View Code
UVA 10253 Series-Parallel Networks