Yue Fei's Battle
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others)Total Submission(s): 173 Accepted Submission(s): 55
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.
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.
3 4 0
2 3
刚开始完全没思路,参考了下面的题解,讲的很清楚
http://blog.csdn.net/xiefubao/article/details/41709957
http://www.cnblogs.com/fraud/p/4141236.html
把树的直径拉开,两边就是两棵二叉树了。子问题:一个深度为m的不同构的二叉树有多少种?
dp[i]表示深度为i的个数。sum[i]表示dp的前缀和。转移方程就是:dp[i+1]=dp[i]*sum[i-1]+dp[i]+dp[i]*(dp[i]-1)/2;
然后回到原问题:如果K是偶数(想象中间有个虚拟的不动点),则两边是两棵深度为K/2的二叉树,答案为:dp[i]*(dp[i]-1)/2+dp[i]
如果K为奇数,则中间还有一个节点:他也是颗二叉树,则分两种大情况:
1.第三个二叉树的深度小于K/2,则sum[K/2-1]*(dp[K/2]*(dp[K/2]-1)/2+dp[K/2])即可;
2.第三个二叉树的深度等于K/2,则分三类讨论:
1. 三棵二叉树结构一样dp[K/2];
2.两棵一样,另一棵不一样:dp[K/2]*(dp[K/2]-1);
3.三棵都不一样:dp[K/2]*(dp[K/2]-1)*(dp[K/2]-2)/6
首先解释一下二叉树的为什么是这样:
对于dp[i],对于长度为i的分支,其端点上只能连接两个子分支(因为另一个要留着与其它分支相连),那么,对于长度为i+1的分支,则只是在长度为i的分支的端点处,增加了一个结点,然后再在新的端点上添加长度为0到i的分支。
a.若添加的分支的长度为0到i-1,则方案数为dp[i]*sum[i-1];
b.若添加的分支的长度为i,两边相同为dp[i],两边不同为dp[i]*(dp[i]-1)/2;
如图所示,深度为i的就变成了深度为i+1的
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=100010;
const int MOD=1000000007;
typedef long long LL;
const LL inv6=166666668;
const LL inv2=500000004;
int K;
LL dp[maxn];
LL sum[maxn];
void init()
{
dp[0]=dp[1]=1;
dp[2]=2;
sum[0]=1;
sum[1]=2;
sum[2]=4;
for(int i=3;i<maxn;i++)
{
dp[i]=(dp[i-1]*sum[i-2]%MOD+dp[i-1]+(dp[i-1]*(dp[i-1]-1+MOD)%MOD)%MOD*inv2%MOD)%MOD;
sum[i]=(sum[i-1]+dp[i])%MOD;
}
}
void solve()
{
int mid=(K/2);
LL ans=((dp[mid]*(dp[mid]-1+MOD)%MOD)%MOD*inv2%MOD+dp[mid])%MOD;
if(K&1)
{
ans=(sum[mid-1]*ans)%MOD;
ans=(ans+dp[mid])%MOD;
ans=(ans+dp[mid]*(dp[mid]-1+MOD)%MOD)%MOD;
ans=(ans+(dp[mid]*(dp[mid]-1+MOD)%MOD)%MOD*(dp[mid]-2+MOD)%MOD%MOD*inv6%MOD)%MOD;
}
cout<<ans<<endl;
}
int main()
{
init();
while(scanf("%d",&K)!=EOF,K)
solve();
return 0;
}