2023.9.23 总结

T1

题面:从左往右有n个格子,编号 1n 。一开始每个格子都有1颗糖果。你总共需要进行 k 次操作,每次操作把从某个格子取 1 颗糖(前提是该格子有糖),放到另一个格子。当 k 次操作全部结束以后,从左往右检查,这 n 个格子的糖果数量。求这 n 个格子总共有多少种不同的状态,答案模 10000000071n200000,1k109
因为最多换 k 次,且只有 n 个位,所以最多只有 min(n,k+1) 个位为 0
那我们可以枚举有 i0 ,有 C(n,i) 种位置为 0 ,挪到其他任意位置上,可一个都不放(就是只有原来那个1),方案数就是一个经典放盘子问题了,即为 C(n,i)×C(n1,i)
最后特判一下全是1即可。

T2

题意:给出一个 n×m 的网格,其中有一些格子是黑色,现定义一个美丽的图为:对于一个黑色格子,它的下面那个格子与它右下面那个格子都需为黑色,现在可以将一些格子染成黑色,求最终有多少个美丽的图?
分析美丽的图的性质,可发现:对于每一列,只有最上面那一个需要染色,对于一个斜行,也只有最左边的需要染色。
当然,已有的需要考虑。
我们可以以此来考虑DP
就是每一列每一列的做,考虑每一个斜行就可以了。

T3

题面:给出包含 n 个整数的数组 a ,其中对于所有的 i ,都满足 1a[i]m。同时 1 ~ ma 中至少出现了一次,请你找出数组 a 的一个长度为 m 的子序列,使得 m 个整数在子序列中恰好只出现 1 次,输出满足条件的字典序最小的子序列。
这道题可以用线段树暴做,这里提供一种贪心的想法。
选出一个满足题目要求的子序列很简单,但是重点是让字典序最小。
很明显,我们希望让越大的数越后选,但是又必须选到这个数,在他最后一次出现切前面没选到的时候就必须选他了。
所以,我们可以这样贪心,开一个数组 v 以及 last ,记录这个数是否选到过以及最后一次出现的位置。
从前往候选,开一个记录选数的序列,若最后选的一个数以后还有且选现在这个数比最后选的一个数优,替换之,否则将其加进去。
时间复杂度 O(n) 可过。
还可以这样:
我们可以从后往前选,随便构造出一个序列,不一定字典序最小,用链表存储。
每次往前找,看一下当前选的这个数放进去之后会不会比原来更优,是则替换之,然后看前一个。

T4

题意:给出一棵树,求不在同一条路径上的三元点对数量。
这道题是正着思考。
从一个节点出发,若有三个节点不在同一路径上,则要不然在他不同的三棵子树,或两个在两棵不同的子树,一个不在自己子树,或者两个或三个节点都在其祖先但不在自己的子树上。
对于最后一种情况,其实考虑到别的节点,还会变成前两种情况。
所以,只考虑前两种情况。
我们令 sizex 为以 x 为子树根节点,子树的节点数量。
对于以 x 为根节点的子树,那么对于第一种情况,就是 (nsizex) 乘上任意两个子树 size 的乘积和。
对于第二种情况,就是任意三个子树 size 的乘积和。
累加输出答案。

T5

题意:给出一个字符串 a ,求有多少个字符串 b ,使得 bba 的子序列。
一个基本的思路,枚举在第 i 个位置分开 a ,前面有个 b ,后面也有个 b
但要统计的是字符串,有可能会有重复,我们要想方法去重。
先预处理出每个位置往后字符 a,b,c,d... 第一次出现的位置,记为 bi,j
动规数组 fi,j 表示从 1 i,x j 中新增了多少个满足的字符串,x 为分开的位置,注意,是新增的字符串。
转移我们只需枚举每个字母,他们对于 i,j 往后第一个出现的位置 x,y ,让 fx,y 加上 fi,j 即可。
这里可以保证一个东西,就是字符串一定在最前面出现。
例如:

abc|abcabc

我们在如图转移时,就会在 f3,6 加上 abc 的答案,而不会在 f3,9 加上。
如何统计答案呢?
若在 x 处分开,第 x 个字符为 A,对于 fi,j ,若 iA 第一次出现是在 x 处,就可以使答案加上 fi,j
因为,如果不是在 x 处,设是在 y 处,就说明之前已经有一次以 y 为分割处理过这个答案了。
举例:

abcabc|abc

我们在做 f3,9 时,中间包含了 abc
3 后第 1 次出现 a 是在 4 ,说明我们在 4 前分割时已处理过这个答案。
最后输出即可。
代码:

#include<bits/stdc++.h>
using namespace std;
const long long mod=998244353;
string a;
long long t[105][55],s,f[105][105];
void dijah(long long x)
{
	long long q=t[1][a[x]-'a'],w;
	if(q==0||q>=x)return;
	memset(f,0,sizeof(f));
	f[q][x]=1;
	for(int i=1;i<x;i++)
	{
		for(int j=x;j<a.size();j++)
		{
			for(int u=0;u<26;u++)
			{
				q=t[i+1][u],w=t[j+1][u];
				if(q&&w&&q<x)f[q][w]+=f[i][j],f[q][w]%=mod;
			}
			q=t[i+1][a[x]-'a'];
			if(q==x)s+=f[i][j],s%=mod;
		}
	}
	return;
}
int main()
{
	cin>>a;
	a=' '+a;
	for(int i=1;i<a.size();i++)
	{
		for(int j=0;j<26;j++)
		{
			for(int u=i;u<a.size();u++)
			{
				if(j+'a'==a[u])
				{
					t[i][j]=u;
					break;
				}
			}
		}
	}
	for(int i=2;i<a.size();i++)dijah(i),s%=mod;
	cout<<s;








  return 0;
}

posted @   dijah  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)
点击右上角即可分享
微信分享提示