CF176B题解

2021/4/18 18:27:12

本文主要是介绍CF176B题解,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Description

给你两个字符串,问你是否可以用恰好 $ k $ 次使第一个字符串前面任意部分移到后面的操作,让其变为第二个字符串。

Method

The essence of demand

如果题目中是有方法可以将第一个字符串转变成第二个字符串的话,那么如果将这两个字符串想像成两个环的话,这两个环应该是相同的,因为题目中的改变的本质就是改变环的起始点。

Idea

这道题比较难想(至少我是看了题解的DP状态才想到的)。

我们首先考虑只有一次操作的时候,这时候答案很显然是前一个字符串所有前面移到后面能成为第二个字符串的次数。

然后考虑有两次操作的时候,这时候有两种情况:

1.将第一个字符串的前面部分通过两次后移成为第二个字符串。

2.将第一个字符串先通过一次转移成为第二个字符串,再将已经成为第二个字符串的字符串做一个不会改变字符串的转换即可。

做到这里,我相信你们已经有了思路,对于一次成功变换他有两种情况一种是从不同到相同,一种是从相同到相同,所以我们只要维护这两种情况的方案即可完成转移,而由于第 $ k $ 次的操作方案数只与第 $ k-1 $ 次操作完全相关,所以这个操作是没有后效性的,所以可以用DP。

Realization

DP state transition equation

\[f_{i,0}=f_{i,1}*sum+f_{i-1,0}*(sum-1) \]

\[f_{i,1}=f_{i-1,0}*(n-sum)+f_{i-1,1}*(n-sum-1) \]

Explanation

$ f_{i,0} $ ---字符串变为目标字符串的方案数。

$ f_{i,1} $ ---字符串变为非目标字符串的方案数

$ sum $ ---一次操作能将一个字符串改变成第二个目标字符串的方案数。

$ f_{i,1}*sum $ ---前面一次不是目标字符串,有 $ sum $ 种方法可以将不是目标的变为目标的。故如此。

$ f_{i,1}* (sum-1) $ ---前面一次是目标字符串,这时候要注意因为 $ sum $ 种方法里是有一种以前一个的起始点为起始点的,因为前面一个是满足为目标字符串的,所以要去掉那种情况。

$ f_{i,1}*(n-sum) $ ---有 $ sum $ 种方法可以变为目标字符串,总方法数为 $ n $ ,故无法转换的方案数为 $ n-sum $ 。

$ f_{i-1,1}*(n-sum-1) $ ---与文同理,也要去掉与前面一次操作重合的情况。

Code

#include<bits/stdc++.h>
using namespace std;
string s,s1,s2;
long long jt,n,Q,MOD,i,j,sum,sum1,sum2,sum3,f[100010][3];
bool flag;
int main()
{
	ios::sync_with_stdio(0);cin.tie();cout.tie();
	cin>>s1;
	cin>>s2;
	cin>>Q;MOD=1000000007;
	n=s1.size();
	for (i=1;i<=n;i++)
         {
             flag=true;jt=0;
             for (j=i;j<n;j++) 
                if (s1[j]!=s2[jt])
                    {
                    	flag=false;break;
					}
			else jt++;
             for (j=0;j<i;j++) 
                 if (s1[j]!=s2[jt])
                     {
                     	flag=false;break;
					 }
			else jt++;
			sum+=flag;
         }
    if (s1==s2) f[0][0]=1;
    else f[0][1]=1;
    for (i=1;i<=Q;i++)
        {
        	f[i][0]=(f[i-1][1]*sum % MOD+f[i-1][0]*(sum-1) % MOD) % MOD;
			f[i][1]=(f[i-1][0]*(n-sum) % MOD+f[i-1][1]*(n-sum-1) % MOD) % MOD; 
		}
	cout<<f[Q][0]<<endl;
	return 0;
}


这篇关于CF176B题解的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程