2025年寒假算法天梯赛 04

C. 古老的打字机

  • 题目往往没有你想象的那么难,所以在否定简单的想法之前,不妨先问问自己这个“漏洞”真的难以解决吗?许多时候,你与正确答案其实只差一步而已
  • 本题最朴素的想法就是直接步步转移\(f_{i,j}\),但是这样肯定不对呀,失配的情况怎么体现呢?于是兜兜转转一圈,推出三方做法后面对“卷积”式的转移束手无策。虽然题目一定是可做的,但这并不代表这种“卷积”式的转移一定可以优化,很可能你的大方向就错了,此时就需要你回顾思维过程。
  • 其实,当“不匹配”的数填入后,它的故事还没有结束,因为它最终一定是要被删掉的,我们不妨等待一下,延迟到删除它的时候再处理
  • 复习一下卡特兰数:关于n个0和n个1的排列,有奇数项为0的特点。但很可惜,它并不能帮你解决这道题
  • 用匹配数j划分阶段 f[i][j]=f[i-1][max(j-1,0)]+f[i-1][j+1]*2 之所以有系数2,是因为退格之后我们并不关心上一个数是否填对,所以可以指定0变成1/指1为0,方案数是一样的,要注意此时第二维就不能只递推到m了,而要与n同阶。
#include <bits/stdc++.h>
using namespace std;
const int mod=1000000007;
int f[5005][5005];
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n;
	cin>>n;
	string s;
	cin>>s;
	int m=s.size();
	f[0][0]=1;
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<=n&&j<=i;j++)
		{
			if(j)
			{
				f[i][j]=f[i-1][j-1];
			}
			else
			{
				f[i][j]=f[i-1][j];
			}
			f[i][j]=(f[i][j]+f[i-1][j+1]*2%mod)%mod;
		}
	}
	cout<<f[n][m]<<endl;
	return 0;
}

D. 倒水问题

  • 有趣的一道题,原来小时候做的倒水问题的本质是扩展欧几里得算法呀。如果排行榜上其他同学没有那么快的AC这道题,你也能一下子就想到结论吗?
#include <bits/stdc++.h>
using namespace std;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int T;
	cin>>T;
	while(T--)
	{
		int a,b,c;
		cin>>a>>b>>c;
		if(c%__gcd(a,b)==0)
		{
			cout<<"Yes\n";
		}
		else
		{
			cout<<"No\n";
		}
	}
	return 0;
}
posted @ 2025-02-09 23:26  D06  阅读(43)  评论(0)    收藏  举报
//雪花飘落效果