Uva 10253 - Series-Parallel Networks (计数+DP)

In this problem you are expected to counttwo-terminal series-parallel networks. These are electric networks consideredtopologically or geometrically, that is, without the electrical properties ofthe elements connected. One of the two terminals can be considered as thesource and the other as the sink. A two-terminal network will be consideredseries-parallel if it can be obtained iteratively in the following way:

• A single edge is two-terminal series-parallel.

• If G1 and G2 are two-terminalseries-parallel, so is the network obtained by identifying the sources andsinks, respectively (parallel composition).

• If G1 and G2 are two-terminalseries-parallel, so is the network obtained by identifying the sink of G1 withthe source of G2 (series composition).

 Notehere that in a series-parallel network two nodes can be connected by multipleedges. 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 isalso an equivalence operation. For example, the following three networks arealso equivalent: Now, given a number N, you are expected to count the number oftwo-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 aninteger N (1 ≤ N ≤ 30) specifying the number of edges in the network. A linecontaining a zero for N terminates the input and this input need not beconsidered.

 

Output

For each N in the input file print a linecontaining the number of two-terminal series-parallel networks that can beobtained using exactly N edges.

 

Sample Input

1

4

15

0

 

Sample Output

1

10

1399068

 

【题意】

串并联网络有n个端点,一个叫源,一个叫汇,递归定义:

1.一条单独的边是串并联网络

2.若G1,G2是串并联网络,把它们的源和汇连在一起也能得到串并联网络(并联)

3.若G1,G2是串并联网络,把G1的汇和G2的源连在一起也能得到串并联网络(串联)

串并联网络中串联或并联在一起的各个部分可以互相调换顺序,即只算一种情况。给定正整数n,统计共有多少个n条边的串并联网络。

 

【思路】

   书上讲的动态规划思路感觉特别神,自己做是肯定想不出来的。每个串并联网络都可以看成是一棵树,并联或串联是非叶子结点,单边是叶子结点,所以这道题问的就是符合:具有n个叶子结点且每个非叶子结点至少有两个子结点(由至少两部分串联或并联)的树的数目f(n),乘以2得所求结果(根结点为串联或并联决定了两种不同的网络)

   如果要直接求解f(n)的话,那么就要枚举n的所有整数划分,比如枚举到n=24,24=(4+4+4)+(6+6)时,结果就要加上C(f(4)+3-1,3)*f(f(6)+2-1,2),这是一个可重复选择的组合问题。现在假设dp(i,j) 表示子树最多有i个叶节点,当前树共有j个叶节点时对应树的数量,那么答案f(n)=dp(n-1,n),而dp(i,j)=sum{dp(i-1,j-p*i)*C(f(i)+p-1,p)|p>=0,p*i<=j},这样就可以递推结果了,但是边界条件比较复杂dp(i,0)=1(i>=0),dp(i,1)=1(i>=1),dp(0,i)=0(i>=1)


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 50;

int n;
ll dp[maxn][maxn];//dp[i][j]表示子树最多有i个叶节点,当前树共有j个叶节点时对应树的数量 
ll f[maxn];//f[n]记录n条边的解 

ll C(ll n, ll m) {//计算组合数 
	double ans = 1;
	for (int i = 0; i < m; i++) ans *= n - i;
	for (int i = 0; i < m; i++) ans /= i + 1;
	return ll(ans + 0.5);
} 

void init() {
	f[1] = 1;
	memset(dp, 0, sizeof(dp));
	
	for (int i = 0; i <= 35; i++) dp[i][0] = 1;
	for (int i = 1; i <= 35; i++) { dp[i][1] = 1; dp[0][i] = 0;}
	
	for (int i = 1; i <= 35; i++) {
		for (int j = 2; j <= 35; j++) {
			dp[i][j] = 0;
			for (int p = 0; p*i <= j; p++) {
				dp[i][j] += C(f[i]+p-1, p)*dp[i - 1][j - p*i];
			}
		}
		f[i + 1] = dp[i][i + 1];
	}
}

int main() {
	init();
	while (scanf("%d", &n) == 1 && n) {
		if (1 == n) { printf("1\n"); continue; }
		printf("%lld\n", 2*f[n]);
	}
	return 0;
}


posted @ 2017-12-24 14:06  不想吃WA的咸鱼  阅读(199)  评论(0编辑  收藏  举报