杭电 1297 Children’s Queue .

http://acm.hdu.edu.cn/showproblem.php?pid=1297

 

计算F(n):

一:当最后一个是男孩M时候,前面n-1个随便排出来,只要符合规则就可以,即是F(n-1);

二:当最后一个是女孩F时候,第n-1个肯定是女孩F,这时候又有两种情况:

        1)前面n-2个可以按n-2个的时候的规则来,完全可以,即是F(n-2);

        2)但是即使前面n-2个人不是合法的队列,加上两个女生也有可能是合法的。当第n-2是女孩而n-3是男孩的情况,可能合法,情况总数为F(n-4);

综上所述:总数F(n)=F(n-1)+F(n-2)+F(n-4);并且,F(0)=1,F(1)=1,F(2)=2,F(3)=4。

 

用递归做,超时

#include<iostream>
using namespace std;
int f(int);
int main()
{
	int n; 
	while(cin>>n)
		cout<<f(n)<<endl;
	return 0;
}
int f(int n)
{
	if(n==0||n==1)
		return 1;
	else if(n==2) 
		return 2;
	else if(n==3) 
		return 4;
	else 
		return f(n-1)+f(n-2)+f(n-4);
}


改用循环做,答案错误

#include <iostream>
using namespace std;
int main()
{
	int i,n,a[50];
	a[0]=1;
	a[1]=1;
	a[2]=2;
	a[3]=4;
	for(i=4;i<=50;i++)
		a[i]=a[i-1]+a[i-2]+a[i-4];
	while(cin>>n)
	{
		cout<<a[n]<<endl;
	}
	return 0;
}


要考虑大数据,大数相加模板为

//大数加法 
string add(string s1,string s2)
{
    
    int j,l,la,lb;
    string max,min;
    max=s1;min=s2;
    if(s1.length()<s2.length()) {max=s2;min=s1;}
    la=max.size();lb=min.size();
    l=la-1;
    for(j=lb-1;j>=0;j--,l--) max[l] += min[j]-'0';   //用到加法运算符,全部按照asiic码表来,就会多加一次48,所以要减去ascii值为48的‘0’
    for(j=la-1;j>=1;j--) if(max[j]>'9'){max[j]-=10;max[j-1]++;}
    if(max[0]>'9') {max[0]-=10;max='1'+max;}
    return max;
}


综上可得

#include<iostream>
#include<string> 
using namespace std;
string add(string s1,string s2)
{
    
    int j,l,la,lb;
    string max,min;
    max=s1;min=s2;
    if(s1.length()<s2.length()) {max=s2;min=s1;}
    la=max.size();lb=min.size();
    l=la-1;
    for(j=lb-1;j>=0;j--,l--) max[l] += min[j]-'0'; 
    for(j=la-1;j>=1;j--) if(max[j]>'9'){max[j]-=10;max[j-1]++;}
    if(max[0]>'9') {max[0]-=10;max='1'+max;}
    return max;
}
int main(){
	int n,i;
	string a[1001];
	a[0]="1";
	a[1]="1";
	a[2]="2";
	a[3]="4";
	for(i=4;i<1001;++i)
	   a[i]=add(add(a[i-1],a[i-2]),a[i-4]);
	 while(cin>>n)
	    cout<<a[n]<<endl;
	return 0;	  
}


 

 

你可能感兴趣的:(杭电 1297 Children’s Queue .)