首页 > 其他分享 >P3989 [SHOI2013]阶乘字符串 题解

P3989 [SHOI2013]阶乘字符串 题解

时间:2023-02-24 13:46:05浏览次数:47  
标签:P3989 cm 0.1 题解 next int text 阶乘 hspace

由于一些不可抗拒的原因,\(n\ge 22\) 无解。

那么只用考虑 \(n\le21\) 的情况即可。

由于 \(n\) 的范围缩小,导致状压又可以重新使用,所以考虑状压。

设 \(f_i\) 为 \(i\) 中所有的集合能被表示的最小下标。

那么对于任何一位 \(j\) 如果在 \(i\) 中,那么:

\(f_i=\max(next(f_{i\oplus j},j))\hspace{0.2cm}\text{其中}\hspace{0.1cm}next(x,y)\hspace{0.1cm}\text{表示第一个在}\hspace{0.1cm}x\hspace{0.1cm}\text{后面出现的字符}\hspace{0.1cm} y\hspace{0.1cm}\text{的下标}\)

因为本集合中的所有情况都得满足,所以下标得取最大值。

那么我们只需预处理出来 \(next\) 即可。

从后往前枚举,本位的 \(next\) 可以由上位继承,也要取上一位,设字符串中 \(s_{i+1}\) 为 \(c\) 那么:

\(next_{i,j}=next_{i+1,j}\)

\(next_{i,c}=i+1\)

预处理出来,然后状压 dp,dp 时对每个状态枚举 \(1\) 的位置即可。

详细看代码。

希望有大佬可以指明下为何 \(n\ge22\) 无解。

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char s[505];
int n,vis[505][26],f[1<<21];
int main()
{
	freopen("factorial.in","r",stdin);
	freopen("factorial.out","w",stdout);
	int T;
	scanf("%d",&T);
	while(T--)
	{
		memset(vis,0,sizeof(vis));
		memset(f,0,sizeof(f));
		scanf("%d",&n);
		scanf("%s",s+1);
		if(n>21)
		{
			printf("NO\n");
			continue;
		}
		int len=strlen(s+1);
		for(int i=0;i<n;i++)vis[len][i]=vis[len+1][i]=len+1;
		for(int i=len-1;i>=0;i--)
		{
			for(int j=0;j<n;j++)vis[i][j]=vis[i+1][j];
			vis[i][s[i+1]-'a']=i+1;
		}
		for(int i=0;i<1<<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				if(i&(1<<j))
				{
					f[i]=max(f[i],vis[f[i^(1<<j)]][j]);
				}
			}
		}
		if(f[(1<<n)-1]!=len+1)printf("YES\n");
		else printf("NO\n");
	}
	return 0;
}

标签:P3989,cm,0.1,题解,next,int,text,阶乘,hspace
From: https://www.cnblogs.com/gmtfff/p/p3989.html

相关文章

  • AT655 玉座の間 题解
    首先我们要学习一下费用流。费用流是什么呢,可以理解为边带权值的网络流。那么最小费用最大流,是指在满足最大流的情况下的最小费用。那么我们就要实现这个过程。首先对......
  • P3997 [SHOI2013]扇形面积并 题解
    理解题意后可以把题目看成一个覆盖线段的问题。对于点在\(-m\)上,看成在\(m\)上。对于\(l<r\),不用处理。对于\(l>r\),将问题看成\((l,m)\)和\((-m+1.r)\)两个区......
  • P5616 [MtOI2019]恶魔之树 题解
    期望就是来搞笑的。由于有最小公倍数,所以可以想到分解质因数,对于多个数求最小公倍数,取每个质因子的最大指数,最后相乘即可。既然都知道了这个,那么就想到先统计每个数的个......
  • CF10E Greedy Change 题解
    一个非常离谱的题。首先有结论,如果有\(w\)使贪心不为最优解,那么比\(w\)小的第一个\(a_i\),用贪心法求面值为\(a_i-1\),除了最后选的一个数\(a_j\)会比原方法多选一......
  • P2161 [SHOI2009]会场预约 题解
    没事打了个Splay,然后调了3h。觉得题解的找前驱后继与删除复杂了点,主要讲一下这的思路。由于平衡树中每一个点代表的区间互不相交,所有平衡树满足\(l,r\)两个值的BST。......
  • P3224 [HNOI2012]永无乡 题解
    典型Splay练习题。开始建\(n\)个Splay,每一次建边用并查集判断是否在一个子图,不在就合并,即把一个Splay的所有点全插入到另一个Splay中,需要合并的点可以用vector存储。但......
  • P1763 埃及分数 题解
    做完后发现很多题解都是有些细节问题的,对于向上与向下取整非常混乱。第一次做迭代加深搜索的题,记录一下。所谓迭代加深搜索,就是在求搜索树的深度的问题中,枚举层数,取最优......
  • P4048 [JSOI2010]冷冻波 题解
    首先很好想到我们应该预处理出来每一个巫妖王能攻击到的精灵。那么这就是一个几何题。对于每一组精灵与巫妖王,设巫妖王坐标为\((x_1,y_1)\),精灵坐标为\((x_2,y_2)\)。......
  • P7221 [JSOI2010] 蔬菜庆典 题解
    本题解在求无解的情况下优化了下。通过分析样例,我们可以发现如果一个节点有多个Dlihc,那么这些Dlihc对应的权值必须一样,否则可以无限延伸下去。因为一号节点没有Tnera......
  • P3195 [HNOI2008]玩具装箱 题解
    首先先写dp方程非常简单\(\mathit{f}_{i}=\min(\mathit{f}_{j}+(\mathit{c}_{i}+i-j-1-L-\mathit{c}_{j})^2)\)(其中\(\mathit{c}_{i}\)表示长度前缀和)然后发现括号......