CCF CSP202006-4 1246(c++动态规划)

在这里插入图片描述
在这里插入图片描述


思路分析

算法:动态规划

发现每一次数字是有规律的:
规律式子:str_map[i] = str_map[i - 3] + str_map[i - 1].substr(str_map[i - 4].size()) + str_map[i - 2];
在这里插入图片描述
如上图:用i表示行号;
i = 1,str[1] = 2;
i = 2,str[2]= 4;
i = 3,str[3] = 16;
i = 4,str[4] = str[1] + str[3].substr(str[0].size()) + str[2] = 2 + 6 + 4 = 264;
i = 5,str[5] = str[2] + str[4].substr(str[1].size()) + str[3] = 4 + 64 + 16 = 46416;

如此类推,可知
str[i] = str[i - 3] + str[i - 1].substr(str[i - 4].size()) + str[i - 2];
但是这个地方仍然存在一个问题,每次产生的新的字符串长度在第40时会出现string类型内存不够分配问题,还未解决该问题,但可能通过链表连接字符串的方法能够解决内存不够的问题。
这个问题导致我的实现与暴力遍历的方法一样只有32分,但是暴力遍历的原因肯定是运行超时的问题。


代码解析

//算法:动态规划
#include<iostream>
#include<string>
#include<map>
using namespace std;
int main()
{
    
    
	ios::sync_with_stdio(false);
	int n, s;
	cin >> n >> s;
	string s_num = to_string(s);
	string str_map[1000];
	str_map[0] = string("1");
	str_map[1] = string("2");
	str_map[2] = string("4");
	str_map[3] = string("16");
	for (int i = 4; i <= n; ++i)
		str_map[i] = str_map[i - 3] + str_map[i - 1].substr(str_map[i - 4].size()) + str_map[i - 2];
	int pos = 0, ans = 0;
	string str = str_map[n];
	while (1) {
    
    
		pos = str.find(s_num, pos);
		if (pos == -1)
			break;
		pos++;
		++ans;
		if (ans >= 998244353)
			ans %= 998244353;
	}
	cout << ans << endl;
	return 0;
}

测试结果
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44116998/article/details/107602422