NOIP模拟 track

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

  • 这道题看着有字符串就直接想到了字符串匹配
  • 我们可以用f[i][j][k]来表示当走到i秒时j高度时已经匹配到第k个的时候的数量
  • 我们有这几种转移方式
  • 当这一位我们向上时
    • 若匹配成功f[i+1][j+1][k+1]+=f[i][j][k]
    • 匹配失败就是f[i+1][j-1][0]+=f[i][j][k](注意这里j不能为0)
  • 往下走时类似
  • 但这样我们会发现太浪费了,而且其中有部分没有计算到
  • 我们想到了字符串匹配中当我们失配可以不用回到0,而是上一个相似的地方
  • 就如s1=1234123123与s2=123412341234…(省略)匹配时
  • 我们在s2中搜到第二个1234时可以不用从0开始,而是直接与s1中的1234连上
  • 所以我们只需要再预处理一次即可
  • 具体看代码
#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
const int Max = 205;
int n,f[Max][Max][Max];
char s[Max];
int len,fail[Max][2],nxt[Max];
void Get()
{
	int j = 0;
	nxt[0] = nxt[1] = 0;
	for (int i = 1; i < len; i++)
	{
		while(j > 0 && s[i] != s[j]) j = nxt[j];
		if (s[i] == s[j]) j++;
		nxt[i + 1] = j;
	}
	
	fail[0][s[0] == 'U'] = 1;
	for (int i = 1; i <= len; i++)
	{
		int pos = i;
		while (pos && s[pos] != 'U') pos = nxt[pos];
		fail[i][1] = pos + 1;
		if (pos == 0 && s[0] == 'D') fail[i][1] = 0;
		pos = i;
		while (pos && s[pos] != 'D') pos = nxt[pos];
		fail[i][0] = pos + 1;
		if (pos == 0 && s[0] == 'U') fail[i][0] = 0;
	}
	return;
}
int main()
{
//	freopen("track.in","r",stdin);
//	freopen("track.out","w",stdout);
	cin >> n;
	scanf("%s", s);
	len = strlen(s);
	if (n&1)
	{
		printf("0\n");
		return 0;
	}
	Get();
	f[0][0][0] = 1;
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j <= min(i, n-i); j++)
		{
			for (int k = 0; k < len; k++)
			{
				if (s[k] == 'U')
				{
					f[i + 1][j + 1][k + 1] = (f[i + 1][j + 1][k + 1] + f[i][j][k]) % mod;
					if (j) f[i + 1][j - 1][fail[k][0]] = (f[i + 1][j - 1][fail[k][0]] + f[i][j][k]) % mod;
				}
				else
				{
					f[i + 1][j + 1][fail[k][1]] = (f[i + 1][j + 1][fail[k][1]] + f[i][j][k]) % mod;
					if (j) f[i + 1][j - 1][k + 1] = (f[i + 1][j - 1][k + 1] + f[i][j][k]) % mod;
				}
			}
			f[i + 1][j + 1][len] = (f[i + 1][j + 1][len] + f[i][j][len]) % mod;
			if (j) f[i + 1][j - 1][len] = (f[i + 1][j - 1][len] + f[i][j][len]) % mod;
		}
	}
	cout << f[n][0][len];
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
NOI(全国青少年信息学奥林匹克竞赛)模拟赛的测试数据是指用于评测参赛选手的程序的输入和对应的输出。测试数据是非常重要的,因为它决定了参赛选手的程序能否正确地解决问题。 在NOI模拟赛中,测试数据具有以下特点: 1.充分覆盖:测试数据应涵盖各种可能的输入情况,包括边界条件和极端情况。通过提供不同的测试数据,可以考察选手对问题的全面理解和解决能力。 2.随机性和均衡性:为了公平起见,测试数据应该是随机生成的,而不是针对某个特定算法或解法设计的。同时,测试数据应该是均衡的,即各种情况的概率应该大致相等,以避免偏向某些解法。 3.合理性和可行性:测试数据应该是合理和可行的,即符合题目要求的输入数据,并且是选手能够通过编写程序来处理的。测试数据应该考虑到程序的限制和时间复杂度,以充分测试选手的编程能力。 NOI模拟赛的测试数据通常由经验丰富的考题组负责生成。他们会根据题目的要求和限制,设计出一组合理、充分、随机和均衡的测试数据,以确保参赛选手的程序在各种情况下都能正确运行,并且能通过性能测试。 总之,测试数据在NOI模拟赛中起到了至关重要的作用,它既考察了选手对问题的理解和解决能力,又提高了选手编程的技巧和效率。同时,合理和恰当的测试数据也是公平竞赛的保证,确保每个参赛选手有相同的机会和条件进行竞争。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值