HDUOJ 6806 Equal Sentences

HDUOJ 6806 Equal Sentences

题目链接

Problem Description

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.

Input

The first line of the input gives the number of test cases, T(1≤T≤100). T test cases follow.

For each test case, the first line contains an integer n(1≤n≤1e5), the number of words in the sentence.

The second line contains the sentence S consisting of n words separated by spaces. Each word consists of no more than 10 lowercase English letters.

The sum of n in all test cases doesn’t exceed 2e5.

Output

For each test case, print a line with an integer, representing the answer, modulo 1e9+7.

Sample Input

2
6
he he zhou is watching you
13
yi yi si wu yi si yi jiu yi jiu ba yao ling

Sample Output

8
233

动态规划~
建议学动态规划的同学尝试自己找状态转移方程,就对着样例推就行,有些小细节实在找不到错误再来看,否则你看了啥也没学会,DP 的难点就是找状态转移方程,而你若想提高就必须逼着自己去找,而不是直接看别人的题解,那样你永远也学不到 DP 的精髓,我就拿第一个样例来举例说明,用 d p [ i ] dp[i] dp[i] 表示 1 − i 1-i 1i 的相似字符串:

he he zhou is watching you
0 1 2 3 4 5 6
dp[0]=1 dp[1]=1 dp[2]=1 dp[3]=dp[1]*2=2 dp[4]=dp[2]*2+dp[1]=3 dp[5]=dp[3]*2+dp[2]=5 dp[6]=dp[4]*2+dp[3]=8

不难发现,状态转移的标志就是 s [ i ] s[i] s[i] s [ i − 1 ] s[i-1] s[i1] 个单词的判断,如果:

  • s [ i ] = s [ i − 1 ] s[i]=s[i-1] s[i]=s[i1] d p [ i ] = d p [ i − 1 ] dp[i]=dp[i-1] dp[i]=dp[i1]
  • s [ i ] ≠ s [ i − 1 ] s[i]\neq s[i-1] s[i]=s[i1],首先可以得到 d p [ i ] = d p [ i − 2 ] ∗ 2 dp[i]=dp[i-2]*2 dp[i]=dp[i2]2,这很好想,因为第 i − 1 i-1 i1 个单词可以和第 i i i 个单词互换,就有两种情况,乘上 d p [ i − 2 ] dp[i-2] dp[i2] 就是总情况,但是此时还有一个小细节,就是要判断一下 s [ i − 2 ] s[i-2] s[i2] s [ i − 3 ] s[i-3] s[i3] 的关系,如果不相等,试想此时如果两个单词已经换了位置,受限于题目要求单词位置的变动不超过 1 1 1,那么第 i − 1 i-1 i1 个单词可以和第 i i i 个单词就不能互换,此时只需将答案直接加上 d p [ i − 3 ] dp[i-3] dp[i3] 即可,所以状态转移方程就是:
    d p [ i ] = d p [ i − 2 ] ∗ 2 + ( s [ i − 2 ] = = s [ i − 3 ] ? 0 : d p [ i − 3 ] ) dp[i]=dp[i-2]*2+(s[i-2]==s[i-3]?0:dp[i-3]) dp[i]=dp[i2]2+(s[i2]==s[i3]?0:dp[i3])

AC代码如下:

#include
using namespace std;
typedef long long ll;
const int N=1e5+5;
const ll mod=1e9+7;
string s[N];
ll dp[N];
int main(){
    int t,n;
    cin>>t;
    while(t--){
        cin>>n;
        fill(dp,dp+n+1,1);
        for(int i=1;i<=n;i++) cin>>s[i];
        for(int i=2;i<=n;i++){
            if(s[i]!=s[i-1]){
                dp[i]=(dp[i-2]*2)%mod;
                if(i>=3&&s[i-1]!=s[i-2]) dp[i]=(dp[i]+dp[i-3])%mod;
            }else dp[i]=dp[i-1]%mod;
        }
        cout<<dp[n]%mod<<endl;
    }
}

你可能感兴趣的:(动态规划,HDUOJ)