2020杭电多校第四场 1005 Equal Sentences

题目

在这里插入图片描述
题目链接

题目大意给定一个字符串序列,求其有多少个“几乎相等”的序列。

题目中对“几乎相等”的定义为:

  1. 两个字符串序列中每种单词出现的数量需要相同
  2. 每种单词的第i个在两个序列中出现的位置相差不能超过1

根据这个定义,序列本身就是一个“几乎相等”序列。除此之外,任意交换原序列两个相邻的元素,得到的序列是一个“几乎相等”序列。但是参与交换的两个元素不能相同且其中不能有已经参与过交换的

基于这个规则,我们可以使用dp来进行状态统计。

我们设状态 dp[i][0/1]表示前i位的方案数,0代表与上一个进行交换,1代表不与上一个进行交换。

于是不难得出下列转移方程:

d p [ i ] [ 0 ] = { 0 ( s t r [ i ] = s t r [ i − 1 ] ) d p [ i − 1 ] [ 1 ] ( s t r [ i ] ≠ s t r [ i − 1 ] ) dp[i][0] = \left\{\begin{matrix} 0 (str[i] = str[i - 1]) \\ dp[i - 1][1](str[i] ≠str[i-1]) \end{matrix}\right. dp[i][0]={ 0(str[i]=str[i1])dp[i1][1](str[i]=str[i1])
d p [ i ] [ 1 ] = d p [ i − 1 ] [ 0 ] + d p [ i − 1 ] [ 1 ] dp[i][1]= dp[i - 1][0] + dp[i - 1][1] dp[i][1]=dp[i1][0]+dp[i1][1]
不要忘记初始化:
d p [ 1 ] [ 0 ] = 0 dp[1][0]=0 dp[1][0]=0
d p [ 1 ] [ 1 ] = 1 dp[1][1]=1 dp[1][1]=1

答案就是:
a n s = d p [ n ] [ 0 ] + d p [ n ] [ 1 ] ans=dp[n][0]+dp[n][1] ans=dp[n][0]+dp[n][1]
不要忘记取模!!!!

代码:

#include<iostream>
#include<cstring>
using namespace std;
const int N = 1e5 + 50;
const int mo = 1e9 + 7;
long long dp[N][2];
char a[N][20];
int n,T;
int main(){
    
    
	for(cin >> T;T;T--){
    
    
		cin >> n;
		for(int i = 1;i <= n;i++){
    
    
			cin >> a[i];
		}
		dp[1][0] = 0;
		dp[1][1] = 1;
		for(int i = 2;i <= n;i++){
    
    
			if(!strcmp(a[i],a[i - 1])){
    
    
				dp[i][0] = 0;
			}else{
    
    
				dp[i][0] = dp[i - 1][1];
			}
			dp[i][1] = (dp[i - 1][0] + dp[i - 1][1]) % mo;
		}
		cout << (dp[n][0] + dp[n][1]) % mo<< endl;
	}
}

猜你喜欢

转载自blog.csdn.net/wayne_lee_lwc/article/details/107709585