UVA 10253 Seris-Parallel Networks

https://vjudge.net/problem/UVA-10253

题目

串并联网络有两个端点,一个叫源,一个叫汇,递归定义如下。

(1)一条单独的边是串并联网络。

(2)若G1和G2是串并联网络,把他们的源和汇分别接在一起也能得到串并联网络。

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

其中规则2说的是并联,规则3说的是串联。

串联的各部分可以改变顺序,并联的各部分可以改变顺序,都看作一种串并联网络。

输入n,输出有多少个n条边的串并联网络。$1\leqslant n\leqslant 30$

题解

每个串并联网络都可以看成一棵树,每次串并联都生成一个节点,串并联的部分是它的儿子,叶子是单独的边

所以问题可以转换为n个叶子能得到多少种树,兄弟顺序无关,每个节点要么没有儿子,要么大于两个儿子

那么可以用背包,划分第一层

dp[i][j]表示有i个叶子,现在划分有j个叶子的子树,有多少种方法

f(x)表示含x个叶子的树有多少种,$f(x)=dp[x][x-1]$,因为每个节点要么没有儿子,要么大于两个儿子

$dp[i][j]=\sum dp[i-j*n][j-1]\times C(f(j)+n-1,n)$

得到树以后还需要指定第一层是串联还是并联

还有一些边界情况

AC代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define REPE(i,a,b) for(int i=(a); i<=(b); i++)
#define PERE(i,a,b) for(int i=(a); i>=(b); i--)
using namespace std;
typedef long long ll;
ll dp[37][37],f[37];
ll C(ll n, ll m) {
	double ans=1;
	REP(i,0,m) {
		ans*=n-i;
	}
	REPE(i,1,m) {
		ans/=i;
	}
	return ll(ans+0.5);
}
int main() {
	REPE(i,0,30) dp[0][i]=1;
	REPE(i,1,30) dp[i][0]=0,dp[1][i]=1;
	f[1]=1;

	REPE(j,1,30) {
		REPE(i,2,30) {
			dp[i][j]=0;
			for(int n=0; n*j<=i; n++) {
				dp[i][j]+=dp[i-j*n][j-1]*C(f[j]+n-1,n);
			}
		}
		f[j+1]=dp[j+1][j];
	}
	int N;
	while(~scanf("%d", &N) && N) {
		printf("%lld\n", N==1?1:f[N]*2);
	}
}

原文地址:https://www.cnblogs.com/sahdsg/p/12643693.html

时间: 2024-11-09 04:03:55

UVA 10253 Seris-Parallel Networks的相关文章

UVA 10253 - Series-Parallel Networks(数论+计数问题+递推)

题目链接:10253 - Series-Parallel Networks 白书的例题. 这题也是需要把问题进行转化,一个并联可以分为几个串联,然后串联可以分成边. 如此一来,最后叶子结点种数会是n,问题转化为去分配叶子结点,使得总和为n. 书上有两种方法,一种直接去递归,利用组合数学的方式去计算答案. 一种是推出递推式: 设dp[i][j]为一共j个叶子结点的树,子树的叶子最多的为i个的情况.然后对于一颗树,枚举恰好包含i个叶子的子树为p棵,那么相当于从f[i]颗树中选出p棵树的方案数,是可重

UVa 10253 Series-Parallel Networks

<训练指南>中的第二种算法,其实本质上就是个背包.d[i][j]表示,在子树的节点数最大为i的情况下,j个节点的解.当之前的i-1,i-2,....0的结果都已知的时候,d[i][j]自然可根据下式求解: d[i][j]=sum{C(f(i)+p-1,p)*d[i-1][j-p*i] | p*i<=j} 其中f(i)表示恰好有i个节点的子树的数量.而C(f(i)+p-1,p)则表示有p棵i节点子树形成的组合数.然后运用乘法原理,剩余的节点数为j-p*i且包含的子树最多只有i-1个节点.继

UVa 10253 (组合数 递推) Series-Parallel Networks

<训练之南>上的例题难度真心不小,勉强能看懂解析,其思路实在是意想不到. 题目虽然说得千奇百怪,但最终还是要转化成我们熟悉的东西. 经过书上的神分析,最终将所求变为: 共n个叶子,每个非叶节点至少有两个子节点的 树的个数f(n).最终输出2 × f(n) 首先可以枚举一下根节点的子树的叶子个数,对于有i个叶子的子树,共有f(i)种, 设d(i, j)表示每棵子树最多有i个叶节点,一共有j个叶节点的方案数. 所求答案为d(n-1, n) 假设恰好有i个叶子的子树有p棵,因为每个子树互相独立,所以

蓝书例题之UVa 10253 Series-Parallel Networks

挺有趣的一道题 首先转化模型,思路参考蓝书,可得出等同于求共n个叶子,且每个非叶结点至少有两个子结点的无标号树的个数的二倍,设个数为\(f[n]\) 考虑怎么求\(f[n]\),假设有一个\(n\)的整数划分,分别代表每棵子树中的叶节点个数,然后用可重组合,乘法原理和加法原理把\(f[n]\)递推出来 这个过程可以用\(dp\)来完成,设\(g[i][j]\)表示子树中叶结点数量最大值小于等于\(i\),共有\(j\)个叶结点的树的个数,转移时枚举最大的叶结点数量\(i\)和叶结点数量为\(i\

dp题目列表

10271 - Chopsticks 10739 - String to Palindrome 10453 - Make Palindrome 10401 - Injured Queen Problem 825 - Walking on the Safe Side 10617 - Again Palindrome 10201 - Adventures in Moving - Part IV 11258 - String Partition 10564 - Paths through the Ho

UVa10253

10253 Series-Parallel NetworksIn this problem you are expected to count two-terminal series-parallel networks. These are electricnetworks considered topologically or geometrically, that is, without the electrical properties of theelements connected.

uva 1590 - IP Networks(IP地址)

习题4-5 IP网络(IP Networks, ACM/ICPC NEERC 2005, UVa1590) 可以用一个网络地址和一个子网掩码描述一个子网(即连续的IP地址范围).其中子网 掩码包含32个二进制位,前32-n位为1,后n位为0,网络地址的前32-n位任意,后n位为0. 所有前32-n位和网络地址相同的IP都属于此网络. 例如,网络地址为194.85.160.176(二进制为11000010|01010101|10100000|10110000), 子网掩码为255.255.255.

Uva 1590 IP Networks

这道题目是一道关于IP地址的题目,要深入理解这道题需要有一定的网络基础. 这道题目我第一次做的时候虽然也AC了,但代码写的比较复杂,不够精炼.近期刚刚参加了网络方面的培训,在有一定知识的基础上,又重写了这道题目.将很多步骤通过位运算(如移位,异或)进行了简化,在此贴一下前后两次的代码. 第二次代码: 1 #include <cstdio> 2 const int maxn = 1000 + 10; 3 int IPs[maxn][4]; 4 int find_firstdiff(int m){

UVA 1590 IP Networks JAVA

题意:输入m代表接下来的数据个数,计算接下来输入数据的网络掩码,和最小网络地址. 思路:①子网掩码:先将数据转为二进制,判断从哪一位开始有数据不一样,记下下标index,则子网掩码是index的前面是1,后面是0(2#),就是子网掩码,再转为10#输出: ②最小网络地址:用任意一个IP与子网掩码进行按位与运算得出最小IP,与运算的符号为&. 1 import java.util.Scanner; 2 3 public class UVA1590 { 4 5 public static void