1236: 愚蠢的摄影师
时间限制: 1 Sec 内存限制: 128 MB题目描述
背景
"如果两个人相差一秒出生, 其中一个是小孩, 那么另一个也是小孩. 由此可以推论, 所有人均是小孩."
问题
数计系是一个由N个人组成的大家庭, 分别为1, 2, 3, ..., N岁.
有一次系主任想为全系拍张合照. 需要所有学生站成一排. 起先他想按他们的岁数从小到大安排, 但后来又觉得这样不自然. 于是他建议按如下方案站排:
1岁的在最左边.
每相邻两人不得相差超过2岁.
这样学生的岁数看起来显得很平均(25岁和27岁的人差别很难看出).
存在多种方案满足此要求.
摄影师不想违反系主任的意愿, 就为每种可能的安排分别拍了一张照片.
输入
整数N, 1<=N<=55.
输出
所拍照片张数.
样例输入
4
样例输出
4
提示
若N=4, 则有4种可能的安排: (1,2,3,4), (1,2,4,3), (1,3,2,4) and (1,3,4,2).
来源
分析:
1、第一反应想到的是全排列函数解决,提交时间超限了。。。。。。。。
2、左思右想,始终想不出方案。嘻嘻,就用我超限的程序来找寻规律(递归思想),果然发现了。但是,我始终不明白其中的原理(哎。。。)。
LANGUAGE:C++
CODE(TLE):
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
int main()
{
//freopen("data.txt","r",stdin);
int n;
cin>>n;
int i,cnt=0,a[1005];
for(i=0;i<n;i++)
a[i]=i+1;
do
{
bool flag=true;
for(i=1;i<n;i++){
if(abs(a[i]-a[i-1])>2){
flag=false;
break;
}
}
if(flag)
cnt++;
}while(next_permutation(&a[1],a+n));
cout<<cnt;
return 0;
}
CODE:
#include <iostream>
using namespace std;
int main()
{
//freopen("data.txt","r",stdin);
int n;
cin>>n;
int f[56]={1,1,2};
for(int i=3;i<n;i++)
f[i]=f[i-1]+f[i-3]+1;
cout<<f[n-1];
return 0;
}