2020年蓝桥杯模拟赛 - 9

第九题 序列计数
题目
【问题描述】
小明想知道,满足以下条件的正整数序列的数量:
1. 第一项为 n;
2. 第二项不超过 n;
3. 从第三项开始,每一项小于前两项的差的绝对值。
请计算,对于给定的 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。
思路:记忆化搜索。

#include
#include
#include
#include
#define ll long long

using namespace std;

const int mod = 10000;

ll dp[1010][1010];

ll dfs(int x, int y)
{	
	if(dp[x][y]) return dp[x][y];
	else
	{
		ll rul = 1;
		for(int i=1; i>n;
	start = clock();
	ll ans = 0;
	for(int i=1; i<=n; i++)
	{
		ans =(ans + dfs(n,i)) % mod;
	}
	end = clock();
	printf("%lld\n",ans);	
	cout<<(end - start);
	return 0;
}

但是这么写时间复杂度是O(N^3),只能过掉%80的样例。输入1000后,输出:

2020年蓝桥杯模拟赛 - 9_第1张图片

 递归过程要用掉3043ms,超时。

将递归过程进行优化,dfs(x,y) = 1 + dfs(x,y-1) + dfs(y,abs(x-y)-1),这里的x,y是指,在前一项为x的情况下,(x,1),(x,2)....(x,y)每一项以及其延申项的情况数的和。1为其本身的一种情况(x,y), dfs(x,y-1)为(x,1),(x,2)....(x,y-1)每一项以及其延申项的情况数的和,dfs(y,abs(x-y)-1) 为(x,y)本身 的延申情况和。

#include
#include
#include
#include
#define ll long long

using namespace std;

const int mod = 10000;

ll dp[1010][1010];

ll dfs(int x, int y)
{	
	if(y <= 0) return 0;
	if(dp[x][y]) return dp[x][y];
	else
	{
		dp[x][y] =(1 + dfs(x,y-1) + dfs(y,abs(x-y)-1)) % mod;
		return dp[x][y];
	}
}

int main()
{
	clock_t start,end;	
	int n;
	cin>>n;
	start = clock();
	ll ans = dfs(n,n);
	end = clock();
	printf("%lld\n",ans);	
	cout<<(end - start);
	return 0;
}

 输入1000

2020年蓝桥杯模拟赛 - 9_第2张图片

可见时间节约了很多,复杂度O(N^2).

你可能感兴趣的:(蓝桥杯,dp)