agc020E - Encoding Subsets

题目大意

|S|<=100

题解

标算是状压,这波出题人在地下室

一开始想直接设f[i]来求[1,i],然后枚举结尾重复串再考虑里面的,反演计算

以为里面的子问题可以设成g[i][j]表示循环节为i的长度为j的串的答案,然后假了,比如100100这种情况,100并不能表示成g

实际上直接把里面的暴力递归算即可,写个程序算一下复杂度发现是两亿多,5s随便过

code

懒得加记忆化了

#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define add(a,b) a=((a)+(b))%998244353
#define mod 998244353
#define ll long long
//#define file
using namespace std;

int n,i,j,k,l;
char a[101];

ll dg(char *a,int n)
{
	char A[101];
	ll f[101];
	int i,j,k,l;
	
	memset(f,0,sizeof(f));
	memset(A,0,sizeof(A));
	f[0]=1;
	fo(i,1,n)
	{
		f[i]=f[i-1]*(1+(a[i]=='1'))%mod;
		fd(j,i/2,1)
		{
			fo(k,i-j+1,i) A[i-k+1]=a[k];
			l=0;
			fd(k,i-j,1)
			{
				++l;A[l]=(a[k]=='0')?'0':A[l];
				if (l==j) add(f[i],f[k-1]*dg(A,j)),l=0;
			}
		}
	}
	return f[n];
}

int main()
{
	#ifdef file
	freopen("agc020E.in","r",stdin);
	#endif
	
	scanf("%s",a+1),n=strlen(a+1);
	printf("%lld\n",dg(a,n));
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}
posted @ 2020-09-27 20:22  gmh77  阅读(175)  评论(0编辑  收藏  举报