[hdu5136]Yue Fei's Battle 2014 亞洲區域賽廣州賽區J題(dp)

轉載請註明出處: http://www.cnblogs.com/fraud/           ——by fraudios

 

現場賽的時候因爲有個地方有點小問題,沒有成功AC,致使與金牌失之交臂。api


 

因爲今天下午有點事情,沒法打重現,因此下午只是花了十分鐘作了一道J題,搶了個FB,2333333333less

Yue Fei's Battle

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others)
Total Submission(s): 15    Accepted Submission(s): 3


ide

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
 

題意:規定每一個結點最多連3個點,有若干個結點構成一棵樹,則在樹的直徑爲k時,共有幾種非同構的結構。post

分析:因爲須要考慮非同構的狀況比較複雜,那麼,咱們能夠考慮將這棵樹拆開,先看偶數,偶數比較簡單ui

1.若直徑n爲偶數,則選取這棵樹的直徑的中間那條邊,將其斷開,從而產生長度均爲n/2的兩個分支,爲了保證計數時不會將同構的重複計入,根據組合數學,則方案數爲C(num[n/2]+2-1,2);spa

注:num[i]表示分支長度爲i的非同構的種數。code

  dp[i]表示分支長度從0到i的全部非同構的分支方案數。orm

2.若直徑n爲奇數,則選取這棵樹的直徑上的中點,從而拆分紅長度爲(n-1)/2,長度爲(n-1)/2以及另外一條長度可爲0到(n-1)/2的三個分支。blog

  a.若剩下一條分支的長度爲[0,(n-1)/2-1],根據組合數學,能夠獲得對應的方案數爲dp[(n-1)/2-1]*C(num[(n-1)/2]+2-1,2);

  b.若剩下另外一條分支的長度也爲(n-1)/2,則此狀況下對應的方案數爲C(num[(n-1)/2]+3-1,3);

  即奇數狀況爲dp[(n-1)/2-1]*C(num[(n-1)/2]+2-1,2)+C(num[(n-1)/2]+3-1,3);

接下來考慮num[i]與dp[i]是如何得出的問題:

顯然dp[i]只是一個前綴和,求出num[i]以後累加便可。

對於num[i],對於長度爲i的分支,其端點上只能鏈接兩個子分支(由於另外一個要留着與其它分支相連),那麼,對於長度爲i+1的分支,則只是在長度爲i的分支的端點處,增長了一個結點,而後再在新的端點上添加長度爲0到i的分支。

  a.若添加的分支的長度爲0到i-1,則方案數爲num[i]*dp[i-1];

  b.若添加的分支的長度爲i,則方案數爲C(num[i]+2-1,2);

  即num[i+1]=num[i]*dp[i-1]+C(num[i]+2-1,2);

 1 #include <iostream>
 2 #include <sstream>
 3 #include <ios>
 4 #include <iomanip>
 5 #include <functional>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <string>
 9 #include <list>
10 #include <queue>
11 #include <deque>
12 #include <stack>
13 #include <set>
14 #include <map>
15 #include <cstdio>
16 #include <cstdlib>
17 #include <cmath>
18 #include <cstring>
19 #include <climits>
20 #include <cctype>
21 using namespace std;
22 #define XINF INT_MAX
23 #define INF 0x3FFFFFFF
24 #define MP(X,Y) make_pair(X,Y)
25 #define PB(X) push_back(X)
26 #define REP(X,N) for(int X=0;X<N;X++)
27 #define REP2(X,L,R) for(int X=L;X<=R;X++)
28 #define DEP(X,R,L) for(int X=R;X>=L;X--)
29 #define CLR(A,X) memset(A,X,sizeof(A))
30 #define IT iterator
31 typedef long long ll;
32 typedef pair<int,int> PII;
33 typedef vector<PII> VII;
34 typedef vector<int> VI;
35 const int maxn=100010;
36 ll dp[maxn];
37 ll num[maxn];
38 const int mod=1000000007;
39 ll inv(int x)
40 {
41     int n=mod-2;
42     ll temp=x;
43     ll ret=1;
44     while(n)
45     {
46         if(n&1)ret=ret*temp%mod;
47         temp=temp*temp%mod;
48         n>>=1;
49     }
50     return ret;
51 }
52 int main()
53 {
54     ios::sync_with_stdio(false);
55     ll inv_2,inv_3;
56     inv_2=inv(2);
57     inv_3=inv(3);
58     dp[0]=num[0]=1;
59     dp[1]=num[1]=1;
60     for(int i=2;i<maxn;i++)
61     {
62         dp[i]=(num[i-1]*dp[i-2]%mod+(num[i-1]+1)*num[i-1]%mod*inv_2%mod)%mod;
63         dp[i-1]+=dp[i-2];
64         dp[i-1]%=mod;
65         num[i]=dp[i];
66     }
67     int n;
68     while(cin>>n&&n)
69     {
70         ll ans; 
71         if(n==1)ans=1;
72         else if(n==2)ans=1;
73         else if(n&1)
74         {
75             ans=num[n/2]*(num[n/2]+1)%mod*inv_2%mod*dp[n/2-1]%mod;
76             ans+=num[n/2]*(num[n/2]+1)%mod*(num[n/2]+2)%mod*inv_2%mod*inv_3%mod;
77             ans%=mod;
78         }
79         else 
80         {
81             ans=(num[n/2]*(num[n/2]+1))%mod*inv_2%mod;
82         }
83         cout<<ans<<endl;
84     }
85     return 0;
86 }
代碼君
相關文章
相關標籤/搜索