2020杭电多校第四场 Equal Sentences

第四题:Equal Sentences

题目:

Sometimes, changing the order of the words in a sentence doesn’t influence understanding. For example, if we change “what time is it”, into “what time it is”; or change “orz zhang three ak world final”, into “zhang orz three world ak final”, the meaning of the whole sentence doesn’t change a lot, and most people can also understand the changed sentences well.

Formally, we define a sentence as a sequence of words. Two sentences S and T are almost-equal if the two conditions holds:

  1. The multiset of the words in S is the same as the multiset of the words in T.
  2. For a word α, its ith occurrence in S and its ith occurrence in T have indexes differing no more than 1. (The kth word in the sentence has index k.) This holds for all α and i, as long as the word α appears at least i times in both sentences.

Please notice that “almost-equal” is not a equivalence relation, unlike its name. That is, if sentences A and B are almost-equal, B and C are almost-equal, it is possible that A and C are not almost-equal.

Zhang3 has a sentence S consisting of n words. She wants to know how many different sentences there are, which are almost-equal to S, including S itself. Two sentences are considered different, if and only if there is a number i such that the ith word in the two sentences are different. As the answer can be very large, please help her calculate the answer modulo 109+7.

思路

对于前i个元素,我们可以第i个元素不交换,或者第i-1和第i个元素交换,
那么我们保存下来,前i个能组成不同句子的最大集合,那么如果第i个数和第i-1个数不同,则dp[i]=dp[i-1]+dp[i-2],如果相同,则dp[i]=dp[i-1]。

代码

#include
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef unsigned long long ull;

const int mod=1e9+7; 
const int N=1e5+7;

string s[N];
int dp[N];

int main()
{
	//freopen("test.in","r",stdin);//设置 cin scanf 这些输入流都从 test.in中读取
    //freopen("test.out","w",stdout);//设置 cout printf 这些输出流都输出到 test.out里面去
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	int T;
	cin>>T;
	while(T--)
	{
		int n;
		cin>>n;
		memset(dp,0,sizeof dp);
		dp[0]=1;
		for(int i=1;i<=n;i++)
		{
			cin>>s[i];
		}
		dp[1]=1;
		for(int i=2;i<=n;i++)
		{
			dp[i]=dp[i-1];
			if(s[i-1]!=s[i])
			{
				dp[i]=(dp[i-1]+dp[i-2])%mod;
			}
		}
		cout<<dp[n]<<endl;
	}
	return 0;
}

你可能感兴趣的:(2020杭电多校,动态规划)