hdu 5136 Yue Fei's Battle(计数DP)

Yue Fei‘s Battle

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others)

Total Submission(s): 151    Accepted Submission(s): 48

Problem Description

Yue Fei is one of the most famous military general in Chinese history.He led Southern Song army in the wars against the Jin dynasty of northern China. Yue Fei achieved a lot of victory and hopefully could retake Kaifeng ,the former capital of Song occupied
by Jin. Fearing that retaking Kaifeng might cause the Jin to release former Emperor Song Qinzong, threatening his throne, Emperor Song Gaozong took some corrupted officers‘ advice, sending 12 urgent orders in the form of 12 gold plaques to Yue Fei, recalling
him back to the capital.

Then Yue Fei was put into prison and was killed under a charge of "maybe there is" treason. But later Yue Fei was posthumously pardoned and rehabilitated, and became a symbol of loyalty to the country. The four corrupted officers who set him up were Qin Hui,Qin
Hui‘s wife Lady Wang, Moqi Xie and Zhang Jun. People made kneeling iron statues of them and put the statues before Yue Fei‘s tomb (located by the West Lake, Hangzhou). For centuries, these statues have been cursed, spat and urinated upon by people. (Now please
don‘t do that if you go to Hangzhou and see the statues.)

One of the most important battle Yue Fei won is the battle in Zhuxian town. In Zhuxian town, Yue Fei wanted to deploy some barracks, and connected those barracks with roads. Yue Fei needed all the barracks to be connected, and in order to save money, he wanted
to build as less roads as possible. There couldn‘t be a barrack which is too important, or else it would be attacked by enemies. So Yue Fei required that NO barrack could connect with more than 3 roads. According to his battle theory, Yue Fei also required
that the length of the longest route among the barracks is exactly K. Note that the length of a route is defined as the number of barracks lied on it and there may be several longest routes with the same length K.

Yue Fei wanted to know, in how many different ways could he deploy the barracks and roads. All barracks could be considered as no different. Yue Fei could deploy as many barracks as he wanted.

For example, if K is 3,Yue Fei had 2 ways to deploy the barracks and roads as shown in figure1. If K is 4, the 3 kinds of layouts is shown in figure 2. (Thick dots stand for barracks, and segments stand for roads):

Please bring your computer and go back to Yue Fei‘s time to help him so that you may change the history.

Input

The input consists of no more than 25 test cases.

For each test, there is only one line containing a integer K(1<=K<=100,000) denoting the length of the longest route.

The input ends by K = 0.

Output

For each test case, print an integer denoting the number of different ways modulo 1000000007.

Sample Input

3
4
0

Sample Output

2
3

题意 : 给你一个数 k ,问你构造出直径为k的结构相互不同构的树的个

数?(树上每个点最多连3条边)。

思路 :

t [ i ] 表示 下面图形里有 i个点时,在节点              dp[ i ] 表示 下面图形里有 i个点时,在节点

上加其它点的情况数。(下图为t [ 3 ]).               上加其它点的情况数。(下图为dp [ 4 ])

                                       
                                           

sum[ i ] 为 t[ i ] 的前缀和。

以t [3] 为例 :

如下图:

因为最长为3,所以在一个点上添加的点数不能超过2.

当在第3个节点上添加2个节点时 ,情况数为  t[2] *(t[2]+1)/2。

当添加1或0个时 , 情况数为    t[2] * sum[3-2] 。

即   t[ 3 ] = t[2] *(t[2]+1)/2 +
 t[2] * sum[3-2] 。

同理可推出  t[ i ] = t [ i - 1 ] * (t[ i - 1 ] +1)/2+t[ i - 1 ]*sum[ i - 2 ];

对于dp[i];

当i是偶数时 : 只用考虑 一半  即    dp[ i ]=t [ i / 2 ]*( t [ i / 2 ]+1)/2;

当i是奇数时 :

中间点加小于等于i/2-1个点时 ,情况数为  sum[i/2-1]  *  t [ i / 2 ]*( t [ i / 2 ]+1)/2;

如果中间加了i / 2个点,那么要分3种情况讨论。

1. 3个主链的样子都不一样。那么就是 t [ i / 2 ]*( t [ i / 2 ]-1 )*( t [ i / 2 ]-2),重复情况有6种。

2. 2个主链样子一样第三个不一样,那么就是t [ i / 2 ]*( t [ i / 2 ]-1 ),没有重复。

3. 3个主链都一样,那么就是 t [ i / 2 ]。

即   dp[i]=sum[i/2-1]  *  t [ i / 2 ]*( t [ i / 2 ]+1)/2 +  t [ i / 2 ] + t [ i / 2 ]*( t
[ i / 2 ]-1 ) + t [ i / 2 ]*( t [ i / 2 ]-1 )*( t
[ i / 2 ]-2) /6;

(计算过程注意取模,特别是除法,要求逆元的)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#define LL long long
using namespace std;
const LL mod=1000000007;
const int maxn=100010;

LL dp[maxn],sum[maxn],t[maxn],a,b;
int k;

LL pow_mod(LL num,LL coun)
{
    LL p=num,q=coun,ret=1;
    while(q)
    {
        if(q & 1)  ret=ret*p%mod;
        q>>=1;
        p=p*p%mod;
    }
    return ret%mod;
}

void initial()
{
    a=pow_mod((LL)2,mod-2);
    b=pow_mod((LL)6,mod-2);

    t[0]=1,t[1]=1,t[2]=2;
    sum[0]=1,sum[1]=2,sum[2]=4;
    for(int i=3;i<maxn;i++)
    {
        t[i]=(t[i-1]*(t[i-1]+1)%mod*a%mod+sum[i-2]*t[i-1]%mod)%mod;
        sum[i]=(sum[i-1]+t[i])%mod;
    }

    dp[1]=1,dp[2]=1;
    for(int i=3;i<maxn;i++)
    {
         LL tmp=t[i/2];
         LL res=tmp*(tmp+1)%mod*a%mod;
         if(i%2==0)  dp[i]=res;
         else        dp[i]=(sum[i/2-1]*res%mod+tmp+tmp*(tmp-1+mod)%mod+tmp*(tmp-1+mod)%mod*(tmp-2+mod)%mod*b%mod)%mod;
    }
}

int main()
{
    initial();
    while(scanf("%d",&k)!=EOF)
    {
        if(k==0)  break;
        printf("%I64d\n",dp[k]);
    }
    return 0;
}

hdu 5136 Yue Fei's Battle(计数DP)

时间: 2024-10-09 08:16:46

hdu 5136 Yue Fei's Battle(计数DP)的相关文章

HDU 5136 Yue Fei&#39;s Battle

题意:求直径上有K个点的不同构树个数(每个点度不超过3). 二叉树满足每个点度不超过3,把直径从中间切开,两边就是二叉树了. 设dp[i] = 深度为i的不同构二叉树个数. sum[i] = 深度不超过i的不同构二叉树个数. 那么二叉树的两个分支有3种情况: 一个分支深度为i-1, 另一个分支深度小于i-1,有dp[i-1] * sum[i-2]种方法: 两个分支深度都是i-1,两个分支不一样,有dp[i-1]*(dp[i-1]-1)/2种方法: 两个分支深度都是i-1,两个分支一样,有dp[i

Yue Fei&#39;s Battle(组合计数递推)

//求一个直径为 k 的树有多少种形态,每个点的度不超过 3 // 非常完美的分析,学到了,就是要细细推,并且写的时候要细心 还有除法取模需要用逆元 #include <iostream> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> using namespace std; #define MOD 1000000007 #define L

[hdu5136]Yue Fei&#39;s Battle 2014 亚洲区域赛广州赛区J题(dp)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud 现场赛的时候由于有个地方有点小问题,没有成功AC,导致与金牌失之交臂. 由于今天下午有点事情,无法打重现,所以下午只是花了十分钟做了一道J题,抢了个FB,2333333333 Yue Fei's Battle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others)T

hdu 4901 The Romantic Hero(计数dp)2014多校训练第4场1005

The Romantic Hero                                                                               Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description There is an old country and the king fell in lov

HDU 6377 度度熊看球赛 (计数DP)

度度熊看球赛 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 293    Accepted Submission(s): 130 Problem Description 世界杯正如火如荼地开展!度度熊来到了一家酒吧. 有 N 对情侣相约一起看世界杯,荧幕前正好有 2×N 个横排的位置. 所有人都会随机坐在某个位置上. 当然,如果某一对情

HDU 4832 组合计数dp

Chess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 509    Accepted Submission(s): 198 Problem Description 小度和小良最近又迷上了下棋.棋盘一共有N行M列,我们可以把左上角的格子定为(1,1),右下角的格子定为(N,M).在他们的规则中,"王"在棋盘上的走法遵循十字

HDU4815/计数DP

题目链接[http://acm.hdu.edu.cn/showproblem.php?pid=4815] 简单说一下题意: 有n道题,每到题答对得分为a[ i ],假如A不输给B的最小概率是P,那么A最少要得到多少分. 解题过程: 假设有n道题,每个题有两个状态,胜或者败,假设达到某个分数m有k(计数DP)种方式,那么最后是这个分数的概率是k/pow(2,n).那么A不输给B的概率就是小于等于m的分数的概率和. #include<bits/stdc++.h> const int maxn =

HDU4901 The Romantic Hero 计数DP

2014多校4的1005 题目:http://acm.hdu.edu.cn/showproblem.php?pid=4901 The Romantic Hero Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 393    Accepted Submission(s): 150 Problem Description There i

HDU 4917 Permutation 拓扑排序的计数

题意: 一个有n个数的排列,给你一些位置上数字的大小关系.求合法的排列有多少种. 思路: 数字的大小关系可以看做是一条有向边,这样以每个位置当点,就可以把整个排列当做一张有向图.而且题目保证有解,所以只一张有向无环图.这样子,我们就可以把排列计数的问题转化为一个图的拓扑排序计数问题. 拓扑排序的做法可以参见ZJU1346 . 因为题目中点的数量比较多,所以无法直接用状压DP. 但是题目中的边数较少,所以不是联通的,而一个连通块的点不超过21个,而且不同连通块之间可以看做相互独立的.所以我们可以对