首页 > 代码库 > hdu 5136 Yue Fei's Battle(计数DP)
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
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
题意 : 给你一个数 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)