這道題是排序問題,可以用遞歸方法解決。
計算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。
程序如下,不過這個程序效率好低啊,杭電的oj返回的是超出時間限制。。
#include<iostream>
using namespace std;
int Fun(int);
int main(){
int n; //error 要用大數
while(cin>>n){
cout<<Fun(n)<<endl;
}
}
int Fun(int n){
if(n==0||n==1) return 1;
if(n==2) return 2;
if(n==3) return 4;
return Fun(n-1)+Fun(n-2)+Fun(n-4);
}
好,得了,又是大數的問題。。。。在這上面今後一定要注意。
大數相加,可以用以下模版解決。熟記模版很重要~~
//大數加法
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;
}