题意是计算给定数量的边通过串联并联两种方式,能组成多少种不同的网络。将它转化为一个树形结构,也就是求有多少不同构的树。
代码如下:
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 6 using namespace std; 7 8 typedef long long LL; 9 const int N = 33; 10 LL ans[N]; 11 int s[N], top; 12 13 LL com(LL n, LL m) { 14 LL ret = 1; 15 for (int i = 0; i < m; i++) ret *= n - i, ret /= i + 1; 16 return ret; 17 } 18 19 void dfs(int r, int x) { 20 if (r <= 0) { 21 if (top <= 1) return ; 22 int cnt = 1; 23 LL tmp = 1; 24 for (int i = 1; i <= top; i++) { 25 if (s[i] == s[i + 1]) cnt++; 26 else { 27 tmp *= com(ans[s[i]] + cnt - 1, cnt); 28 cnt = 1; 29 } 30 } 31 ans[x] += tmp; 32 return ; 33 } 34 for (int i = s[top]; i <= r; i++) { 35 s[++top] = i, s[top + 1] = -1; 36 dfs(r - i, x); 37 top--; 38 } 39 } 40 41 void PRE() { 42 ans[1] = 1; 43 for (int i = 2; i < N; i++) { 44 s[top = 0] = 1; 45 ans[i] = 0; 46 dfs(i, i); 47 //cout << i << ' ' << ans[i] << endl; 48 } 49 for (int i = 2; i < N; i++) ans[i] <<= 1; 50 } 51 52 int main() { 53 PRE(); 54 int n; 55 while (cin >> n && n) cout << ans[n] << endl; 56 return 0; 57 }
UPD:
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 6 using namespace std; 7 8 typedef long long LL; 9 const int N = 32; 10 LL dp[N][N], ans[N]; 11 12 LL com(LL n, LL m) { 13 LL ret = 1; 14 for (int i = 0; i < m; i++) { 15 ret *= n - i; 16 ret /= i + 1; 17 } 18 return ret; 19 } 20 21 void PRE() { 22 ans[1] = 1; 23 dp[0][0] = 1; 24 for (int i = 1; i < N; i++) { 25 dp[i][0] = dp[i][1] = 1; 26 for (int j = 2; j < N; j++) { 27 dp[i][j] = 0; 28 for (int k = 0; k * i <= j; k++) { 29 dp[i][j] += com(ans[i] + k - 1, k) * dp[i - 1][j - k * i]; 30 } 31 } 32 ans[i + 1] = dp[i][i + 1]; 33 //cout << ans[i + 1] << endl; 34 } 35 } 36 37 int main() { 38 PRE(); 39 int n; 40 while (cin >> n && n) cout << (n > 1 ? ans[n] << 1 : 1) << endl; 41 return 0; 42 }
——written by Lyon