化妆培训网站源码,网站运营总结,嘉兴php网站开发,手机版oa办公软件正题
P7152 题目大意
对于一个原串#xff08;只有四种字符#xff09;#xff0c;先将所有相邻且相同的字符分割开#xff0c;对分割得到的若干段翻转#xff0c;得到编辑后的字符串#xff0c;现在给出编辑后的字符串#xff08;有一些位置不确定#xff09;#…正题
P7152 题目大意
对于一个原串只有四种字符先将所有相邻且相同的字符分割开对分割得到的若干段翻转得到编辑后的字符串现在给出编辑后的字符串有一些位置不确定问你有多少种符合的原串 解题思路
对于一个编辑后的字符串考虑对其进行分割那么分割合法要满足以下两个条件
每一段中相邻位置不相同如果相同那么对于原串肯定会再分割对于相邻两段a,ba的首字符要和b的结尾字符相同保证在原串中可以被分割
可以考虑DP设fi,chf_{i,ch}fi,ch为前i个字符已经分割好且最后一段的首字符为ch的方案数那么可以从i往后枚举然后传递
但这样显然会TLE题目有说到字符串只有四种字符那么可以考虑从字符下手
设fi,a,b,cf_{i,a,b,c}fi,a,b,c为前i个字符串已经分割好了且上一段首字符为a当前段首字符为b结尾字符为c的方案数计算答案的时候保证a,c相同即可
那么对于新插入的一个字符考虑两种方案
加入最后一段里那么要保证新字符和c不同新开一段那么要保证a,c不同
这样转移时间复杂度为O(n)常数为444^444可以过 code
#includecstdio
#includecstring
#includeiostream
#includealgorithm
#define ll long long
#define N 100010
#define wyc 1000000007
using namespace std;
int n,ans,v[N],f[N][5][5][5];
char c[N];
int main()
{scanf(%s,c1);nstrlen(c1);for(int i1;in;i){if(c[i]?)v[i]0;else if(c[i]A)v[i]1;else if(c[i]C)v[i]2;else if(c[i]G)v[i]3;else v[i]4;}for(int i1;i4;i)for(int j1;j4;j)if(v[1]j||!v[1])f[1][i][j][j]1;for(int i1;in;i)for(int c1;c4;c)if(!v[i]||v[i]c)for(int a1;a4;a)for(int b1;b4;b){if(!v[i1]){for(int d1;d4;d){//的情况if(ac)(f[i1][b][d][d]f[i][a][b][c])%wyc;if(c!d)(f[i1][a][b][d]f[i][a][b][c])%wyc;}}else{if(ac)(f[i1][b][v[i1]][v[i1]]f[i][a][b][c])%wyc;if(c!v[i1])(f[i1][a][b][v[i1]]f[i][a][b][c])%wyc;}}for(int a1;a4;a)for(int b1;b4;b)(ansf[n][a][b][a])%wyc;printf(%d,ans);return 0;
}