hdu 5136 Yue Fei's Battle

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个点的不同构树个数(每个点度不超过3)
分奇数和偶数,如果是偶数,假设前n/2个节点加其他点的情况数为tmp,那么答案就是tmp×(tmp-1)/2+tmp,因为上半部分和下半部分如果不一样,换一下是一种情况,那么就会重复2次,上下一样就不会有重复情况。
到下一个奇数,中间点最多能加n/2个点,但是这样就会有3条主链,所以先不考虑这种,中间点加小于等于n/2-1个点的情况个数是那个tmp的前缀和sum[n/2-1],所以这种情况答案就是sum[k/2-1]*(tmp*(tmp-1)/2+tmp),如果中间加了n/2个点,那么要分3种情况讨论。
1.3个主链的样子都不一样。那么就是tmp*(tmp-1)*(tmp-2)重复情况有3!种也就是6种。
2.2个主链样子一样第三个不一样,那么就是tmp*(tmp-1),没有重复。
3.3个主链都一样,那么就是tmp。
所以最后计算式是sum[n/2-1]*(tmp*(tmp-1)/2+tmp)+tmp*(tmp-1)*(tmp-2)/6+tmp*(tmp-1)+tmp。
最后考虑一下tmp该如何递推,容易看出只需要在偶数的时候递推就可以了,因为下一个奇数还是上一个偶数的tmp。式子跟上一个推导很像tmp = sum[n/2-2]*tmp+tmp*(tmp-1)/2+tmp;意思是在第n/2个节点(之前的已经递推过了)分2种,1种是放小于n/2-1个,另一种是放n/2-1个,那么就是2条主链了。
ac代码:
#include<cstdio>
#include<ctype.h>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
#define NMAX 1000000005
#define MOD 1000000007
long long dp[100005],sum[100005];
int main()
{
    dp[1] = dp[2] = 1;
    sum[0] = 1;
    sum[1] = 2;
    long long tmp = 1;
    for(int i = 3; i <= 100000; i++)
    {
        if(i%2)
        {
            long long a = ((tmp*(tmp-1LL+MOD)%MOD*(tmp-2LL+MOD)%MOD)*166666668LL%MOD + tmp*(tmp-1LL+MOD)%MOD + tmp)%MOD;
            dp[i] = (sum[i/2-1]*((tmp*(tmp-1LL+MOD)%MOD)*500000004LL%MOD+tmp)%MOD+a)%MOD;
        }
        else
        {
            long long a = tmp*sum[i/2-2]%MOD;
            tmp = (tmp*(tmp-1LL+MOD)%MOD*500000004LL%MOD+tmp+a)%MOD;
            dp[i] = (tmp*(tmp-1LL+MOD)%MOD*500000004LL%MOD+tmp)%MOD;
            sum[i/2] = (sum[i/2-1]+tmp)%MOD;
        }
    }
    int n;
    while(~scanf("%d",&n) && n)
    {
        printf("%lld\n",dp[n]);
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值