这是楼教主的男人八题之一。很高兴我能做八分之一的男人了。

题目大意:求有n个顶点的连通图有多少个。

解法:

1、  用总数减去不联通的图(网上说可以,我觉得时间悬)

2、    用动态规划(数学递推)。网上讲的方法我觉得非常难懂,但好像也没有更好的表示。我就说一下吧:

用dp[i]表示i个顶点时的连通图的总数。

考虑将1号点去除后,2号点所在的联通块。设此联通块有k个点,则这块共有C(n-2,k-1)种取法。

回过头来看刚开始的图。可以把图分成两块,一是上述联通块,其余的另一块(此块也一定联通),这两块之间至少有一条连线,而这些线段肯定有一个顶点是1号点(用反证法很容易得到)。K个顶点连线到1号点的情况总共有2^k种,去除一种都不连的情况,还剩(2^k)-1种。故此时共有dp[j]*dp[i-j]*((2^k)-1)*C(n-2,k-1)

综上,dp[i]=sigma{ dp[j]*dp[i-j]*((2^k)-1)*C(n-2,k-1)} (1<=j<i)

最后提醒一句,虽然大家都知道:要用高精度

代码:

#include<cstdio>

#include<cstring>

using namespace std;

int max(int x,int y){

return(x>y)?x:y;

}

struct bign{

int len,p[240];

bign(){

len=1;

memset(p,0,sizeof(p));

}

bign operator =(const bign &o){

len=o.len;

memcpy(p,o.p,sizeof(p));

return *this;

}

bign operator +(const bign &o){

bign ans;

ans.len=max(len,o.len)+1;

int g=0;

for(int i=0;i<ans.len;i++){

int x=p[i]+o.p[i]+g;

ans.p[i]=x%10000;

g=x/10000;

}

if(ans.p[ans.len-1]==0)ans.len--;

return ans;

}

bign operator *(const bign &o){

bign ans;

ans.len=len+o.len;

for(int i=0;i<len;i++)

for(int j=0;j<o.len;j++){

ans.p[i+j]+=p[i]*o.p[j];

ans.p[i+j+1]+=ans.p[i+j]/10000;

ans.p[i+j]%=10000;

}

while(ans.p[ans.len-1]==0)ans.len--;

return ans;

}

void print(){

printf("%d",p[len-1]);

for(int i=len-2;i>=0;i--){

if(p[i]<10)printf("000%d",p[i]);

if(p[i]>=10 && p[i]<100)printf("00%d",p[i]);

if(p[i]>=100 && p[i]<1000)printf("0%d",p[i]);

if(p[i]>=1000 && p[i]<10000)printf("%d",p[i]);

}

printf("\n");

return;

}

}dp[51],tmp,c[51][51],two[51];

void init(bign &x){

x.len=1;

memset(x.p,0,sizeof(x.p));

x.p[0]=1;

return;

}

int main(){

int n;

scanf("%d",&n);

init(two[0]);

for(int i=1;i<=50;i++)

two[i]=two[i-1]+two[i-1];

for(int i=0;i<=50;i++)

two[i].p[0]--;

init(c[0][0]);

for(int i=1;i<=50;i++){

init(c[i][0]);init(c[i][i]);

for(int j=1;j<i;j++)

c[i][j]=c[i-1][j]+c[i-1][j-1];

}

init(dp[2]);init(dp[1]);

for(int i=3;i<=50;i++){

for(int j=1;j<i;j++)

dp[i]=dp[i]+dp[j]*dp[i-j]*two[j]*c[i-2][j-1];

}

while(n!=0){

dp[n].print();

scanf("%d",&n);

}

return 0;

}

poj 1737男人八题之一 orz ltc的更多相关文章

  1. poj 1743 男人八题之后缀数组求最长不可重叠最长重复子串

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 14874   Accepted: 5118 De ...

  2. poj 1741 楼教主男人八题之中的一个:树分治

    http://poj.org/problem? id=1741 Description Give a tree with n vertices,each edge has a length(posit ...

  3. POJ1742 Coins(男人八题之一)

    前言 大名鼎鼎的男人八题,终于见识了... 题面 http://poj.org/problem?id=1742 分析 § 1 多重背包 这很显然是一个完全背包问题,考虑转移方程: DP[i][j]表示 ...

  4. Cogs 1714. [POJ1741][男人八题]树上的点对(点分治)

    [POJ1741][男人八题]树上的点对 ★★★ 输入文件:poj1741_tree.in 输出文件:poj1741_tree.out 简单对比 时间限制:1 s 内存限制:256 MB [题目描述] ...

  5. poj 1742(好题,楼天城男人八题,混合背包)

    Coins Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 33269   Accepted: 11295 Descripti ...

  6. 博弈论(男人八题):POJ 1740 A New Stone Game

    A New Stone Game Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5694   Accepted: 3119 ...

  7. 新男人八题---AStringGame

    终于完成进度男人1/8,为了这题学了sam= = 题意先有一个串,n个子串,两个人轮流每次在子串上加字符,要求加完后还是原串的子串,最后不能加的就是输者,求赢的人 解法:sam之后在构造的状态图上跑s ...

  8. nyoj137 取石子(三) 楼教主男人八题之一

    思路:一堆时,N态.两堆时,当两堆数量相同,P态,不同为N态.三堆时,先手可以变成两堆一样的,必胜N态. 此时可以总结规律:堆数为偶数可能且石子数都是两两相同的,为P态.分析四堆时,当四堆中两两数量一 ...

  9. POJ 1737 Connected Graph 题解(未完成)

    Connected Graph Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 3156   Accepted: 1533 D ...

随机推荐

  1. [LeetCode] Delete Duplicate Emails 删除重复邮箱

    Write a SQL query to delete all duplicate email entries in a table named Person, keeping only unique ...

  2. 【ios开发】UITableViewCell的重用

    移动开发需要解决的一个问题就是资源稀缺的问题.多数情况下是内存问题. 虽然现在的手机都号称大内存,高配置.但是移动app所占用的资源也在跟着不断膨胀, 也是造成内存不足的主要原因. 在前面的例子中,还 ...

  3. [翻译]ES 提案: global

    Jordan Harband 的 ECMAScript 提案“global”现在处于第三阶段.该提案提供了一种新的用于访问全局对象的标准方式. 全局对象的引用 下面是常用的几种引用全局对象的方式: 全 ...

  4. jQuery_mobile页面跳转事件学习

      <html>     <head>         <meta http-equiv="Content-Type" content="t ...

  5. Uncaught SyntaxError: Invalid or unexpected token

    出现错误的地方:在Jquery中,调用有参数的方法,动态传递参数时报错 出现错误的原因: 动态传递参数的时候,参数中有换行符 错误的解决:参数传递之前,将换行符替换 var  temp = model ...

  6. iOS中获取当前时间,设定时间,并算出差值

    NSDate *date = [NSDate date];//获取当前时间 NSTimeZone *zone = [NSTimeZone systemTimeZone];//修改时区 NSIntege ...

  7. 练习JavaScript实现过滤特殊字符

    for循环遍历特殊字符和用户输入字符,然后做比较,返回结果. <script type="text/javascript"> var name = prompt(&qu ...

  8. POJ2175 Evacuation Plan

    Evacuation Plan Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4617   Accepted: 1218   ...

  9. Python 编码简单说

    先说说什么是编码. 编码(encoding)就是把一个字符映射到计算机底层使用的二进制码.编码方案(encoding scheme)规定了字符串是如何编码的. python编码,其实就是对python ...

  10. ES6箭头函数与展开运算符

    箭头函数:省去了关键字function和return: eg: reduce=(a,b)=>a+b;//返回a+b的值 redduce=(a,b)=>{console.log(a);con ...