问题描述
小明想知道,满足以下条件的正整数序列的数量:
第一项为 n;
第二项不超过 n;
从第三项开始,每一项小于前两项的差的绝对值。
请计算,对于给定的 n,有多少种满足条件的序列。
输入格式
每一行包含一个整数n。
输出格式
输出一个整数,表示答案。答案可能很大,请输出答案除以10000的余数。
样例输入
4
样例输出
7
样例说明
以下是满足条件的序列:
4 1
4 1 1
4 1 2
4 2
4 2 1
4 3
4 4
评测用例规模与约定
对于 20% 的评测用例,1 <= n <= 5;
对于 50% 的评测用例,1 <= n <= 10;
对于 80% 的评测用例,1 <= n <= 100;
对于所有评测用例,1 <= n <= 1000。
深度搜索(不推荐,时间过长)
思路,由于前两项和后面几项的规则不同,可以将前两项分开考虑,现将数列的前两位填数,计数器加一,后对数列的第三位开始搜索,由于数列的长度是不一定的(4 1 1 和 4 1 都可以),所以判断条件,如果满足当前项小于前两项的差的绝对值,计数器就加一,如果前两项的差为0或一,表示当前数列已达到最长长度,(如4 1 1 (4 1并不是最长的长度)),返回
#include <iostream>
#include <vector>
#include <cmath>
#include <cstring>
using namespace std;
long long vec[2000];
long long sum=0;
int n;
void dfs(int m, int step)//step表示当前属于数列的第几项
{
int i;
if (abs(vec[step - 1] - vec[step - 2] == 0 || abs(vec[step - 1] - vec[step - 2] == 1)))//判断条件当前数列探索到底,需要返回
return;
for (i = 1; i <= m; i++)
{
if (i < abs(vec[step - 1] - vec[step - 2]))
{
sum =(sum + 1)%10000;
vec[step] = i;//为了防止(4 1)这种不完全数列漏选,符合当前项小于前两项就要加一
dfs(n, step + 1);//进入下一步探索
}
}
}
int main(void)
{
int i;
cin >> n;
for (i = 1; i <= n; i++)
{
memset(vec,0,sizeof(vec));//注意将数组清零
vec[1]=n;
vec[2]=i;
sum =(sum + 1)%10000;//前两项一定满足序列要求,加一
dfs(n, 3);
}
cout << sum%10000 <<endl;
}