传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1297
Children’s Queue
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 16830 Accepted Submission(s): 5643
Problem Description
There are many students in PHT School. One day, the headmaster whose name is PigHeader wanted all students stand in a line. He prescribed that girl can not be in single. In other words, either no girl in the queue or more than one girl stands side by side. The case n=4 (n is the number of children) is like
FFFF, FFFM, MFFF, FFMM, MFFM, MMFF, MMMM
Here F stands for a girl and M stands for a boy. The total number of queue satisfied the headmaster’s needs is 7. Can you make a program to find the total number of queue with n children?
Input
There are multiple cases in this problem and ended by the EOF. In each case, there is only one integer n means the number of children (1<=n<=1000)
Output
For each test case, there is only one integer means the number of queue satisfied the headmaster’s needs.
Sample Input
1 2 3
Sample Output
1 2 4
题目解释:
有n个位置,男孩女孩排队,要求有女孩的话,至少要2个女孩在一起。
解题思路:
1)如果最后一个是男孩,前面n-1是合法队列,则方法数为f(n-1),如果前面n-1个不是合法队列,则这n个也不可能是合法队列
2)如果最后一个是女孩,那么第n-1个必定是女孩
<1>如果前n-2个是合法队列,方法数为f(n-2)
<2>如果前n-2个不是合法队列,那满足条件的队列应该是f(n-4)+男+女,方法数为f(n-4)
所以f(n)=f(n-1)+f(n-2)+f(n-4)
注意:n的值最大是1000,结果非常庞大,要用到大数加法的思想,可以压1位存或者压4位存,压4位存的时候要注意当过程中的“余数”不足4位的时候要前面补0.
看下最大的结果,别怕哈哈哈:12748494904808148294446671041721884239818005733501580815621713101333980596197474744336199742452912998225235910891798221541303838395943300189729514282623665199754795574309980870253213466656184865681666106508878970120168283707307150239748782319037
ac代码:
压4位存
#include<iostream>
using namespace std;
int main()
{
int arr[1001][101]={0};
arr[0][1]=1;
arr[1][1]=1;
arr[2][1]=2;
arr[3][1]=4;
for(int i=4;i<1001;i++)
{
for(int j=1;j<101;j++)
{
arr[i][j]+=arr[i-1][j]+arr[i-2][j]+arr[i-4][j];//
arr[i][j+1]=arr[i][j]/10000;//更新商
arr[i][j]=arr[i][j]%10000;//更新余数
}
}
int num;
while(cin>>num)
{
int k=100;
for(;arr[num][k]==0;k--);//找到待输出的商
cout<<arr[num][k];
for(;k>1;)
{
k--;
cout.width(4);
cout.fill('0');
cout<<arr[num][k];
}
cout<<endl;
}
}
压1位存
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long s[1010][1005];
int main()
{
int i,j,n;
memset(s,0,sizeof(s));
s[1][0]=1;s[2][0]=2;s[3][0]=4;s[4][0]=7;
for(i=5;i<=1000;i++){
for(j=0;j<=1000;j++)
s[i][j]=s[i-1][j]+s[i-2][j]+s[i-4][j];
for(j=0;j<=1000;j++){
if(s[i][j]>=10){
s[i][j+1]+=s[i][j]/10;
s[i][j]%=10;
}
}
}
while(cin>>n){
i=1000;
while(i--){
if(s[n][i]!=0)
break;
}
cout<<s[n][i];
i--;
for(;i>=0;i--)
printf("%d",s[n][i]);
cout<<endl;
}
return 0;
}