HDOJ 4466 Triangle 递推

来源:互联网 发布:考试通软件 编辑:程序博客网 时间:2024/06/05 09:30


1、当b=c时,a至少为1,所以c<=(n-1)/2

而a<=b 所以n-2*c<=c =>c>=n/3; 故共有(n-1)/2-(n/3)+(n/3?0:1)种。

2、当b<c时,肯定有b<=c-1 

此时若a+b>c 则a+b>c-1 

如果a,b,c能构成三角形,则a,b,c-1也一定能够构成三角形。

反过来,如果a,b,c-1能够构成三角形,也即a+b>c-1 当a+b!=c时,一定能使a,b,c构成三角形。故可以通过dp[n-1]递推过来,然后减去a+b=c+1的情况。

此时n=2*c+1,c=(n-1)/2  只有当n为奇数的时候才有可能,而a+b=(n-(n-1)/2),a<=b 所以这种情况共有 (n-(n-1)/2)/2种,化简得(n+1)/4


在考虑有多个三角形的情况。

假设N=a*b 则把b作为一个基本三角形,a个1,作为a个部分,中间有a-1个隔板,每个隔板可选可不选,一共有2^(a-1)种情况。



Triangle

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 607    Accepted Submission(s): 284


Problem Description
You have a piece of iron wire with length of n unit. Now you decide to cut it into several ordered pieces and fold each piece into a triangle satisfying:
*All triangles are integral.
* All triangles are pairwise similar.
You should count the number of different approaches to form triangles. Two approaches are considered different if either of the following conditions is satisfied:
*They produce different numbers of triangles.
* There exists i that the ith (again, pieces are ordered) triangle in one approaches is not congruent to ith triangle in another plan.
The following information can be helpful in understanding this problem.
* A triangle is integral when all sides are integer.
*Two triangles are congruent when all corresponding sides and interior angles are equal.
* Two triangles are similar if they have the same shape, but can be different sizes.
*For n = 9 you have 6 different approaches to do so, namely
(1, 1, 1) (1, 1, 1) (1, 1, 1)
(1, 1, 1) (2, 2, 2)
(2, 2, 2) (1, 1, 1)
(1, 4, 4)
(2, 3, 4)
(3, 3, 3)
where (a, b, c) represents a triangle with three sides a, b, c.
 

Input
There are several test cases.
For each test case there is a single line containing one integer n (1 ≤ n ≤ 5 * 106).
Input is terminated by EOF.
 

Output
For each test case, output one line “Case X: Y” where X is the test case number (starting from 1) and Y is the number of approaches, moduled by 109 + 7.
 

Sample Input
123456891011121519201001000
 

Sample Output
Case 1: 0Case 2: 0Case 3: 1Case 4: 0Case 5: 1Case 6: 2Case 7: 1Case 8: 6Case 9: 3Case 10: 4Case 11: 10Case 12: 25Case 13: 10Case 14: 16Case 15: 525236Case 16: 523080925
 

Source
2012 Asia Chengdu Regional Contest
 


/* ***********************************************Author        :CKbossCreated Time  :2015年09月03日 星期四 10时58分13秒File Name     :HDOJ4466.cpp************************************************ */#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <string>#include <cmath>#include <cstdlib>#include <vector>#include <queue>#include <set>#include <map>using namespace std;typedef long long int LL;const int maxn=5001000;const int mod=1e9+7;int n;LL dp[maxn];int bb[maxn];void init(){dp[3]=1LL;for(int i=4;i<maxn;i++){dp[i]=dp[i-1]+(i-1)/2-i/3+(i%3?0:1);if((i&1)==0) dp[i]-=i/4;dp[i]=(dp[i]+mod)%mod;}bb[1]=1LL;for(int i=2;i<maxn;i++){bb[i]=(bb[i-1]<<1)%mod;for(int j=2;i*j<maxn;j++){dp[i*j]=(dp[i*j]-dp[i]+mod)%mod;}}}int main(){//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);init();int cas=1;while(scanf("%d",&n)!=EOF){LL ans=0;for(int i=1;i*i<=n;i++){if(n%i==0){int d=n/i;ans=(ans+(dp[i]*bb[d])%mod)%mod;if(i*i!=n) ans=(ans+(dp[d]*bb[i])%mod)%mod;}}printf("Case %d: %lld\n",cas++,ans);}        return 0;}



0 0
原创粉丝点击