标签:des style blog http io ar color os sp
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud
现场赛的时候由于有个地方有点小问题,没有成功AC,导致与金牌失之交臂。
由于今天下午有点事情,无法打重现,所以下午只是花了十分钟做了一道J题,抢了个FB,2333333333
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others)
Total Submission(s): 15 Accepted Submission(s): 3
题意:规定每个结点最多连3个点,有若干个结点构成一棵树,则在树的直径为k时,共有几种非同构的结构。
分析:由于需要考虑非同构的情况比较复杂,那么,我们可以考虑将这棵树拆开,先看偶数,偶数比较简单
1.若直径n为偶数,则选取这棵树的直径的中间那条边,将其断开,从而产生长度均为n/2的两个分支,为了保证计数时不会将同构的重复计入,根据组合数学,则方案数为C(num[n/2]+2-1,2);
注:num[i]表示分支长度为i的非同构的种数。
dp[i]表示分支长度从0到i的所有非同构的分支方案数。
2.若直径n为奇数,则选取这棵树的直径上的中点,从而拆分成长度为(n-1)/2,长度为(n-1)/2以及另一条长度可为0到(n-1)/2的三个分支。
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 }
[hdu5136]Yue Fei's Battle 2014 亚洲区域赛广州赛区J题(dp)
标签:des style blog http io ar color os sp
原文地址:http://www.cnblogs.com/fraud/p/4141236.html