1. 程式人生 > 實用技巧 >HDU6806:Equal Sentences——題解

HDU6806:Equal Sentences——題解

http://acm.hdu.edu.cn/showproblem.php?pid=6806

給一個字串 $S$ ,求與其相似的本質不同的字串 $T$ 的個數:

相似的定義:

1.單詞的可重集合相同。

2.對於一個詞 $α$ ,它在 $S$ 中的第 $i$ 次出現和在 $T$ 中的第 $i$ 次出現的指數相差不超過1。

我會做的題當中唯一一道值得寫題解的。

首先用map處理一下單詞,給單詞標號,就可以把字串換成數列了。

之後可以發現,構造一個相似字串的方法就是選擇兩個相鄰的單詞然後交換位置即可。

並且我們能夠發現如果相鄰兩個單詞一樣那麼交換與不交換沒有差別。

那麼設 $f[i]$ 為前 $i$ 個單詞所組成的字串的本質不同的字串的個數,那麼有:

如果 $a[i]==a[i-1]$ ,那麼 $f[i]=f[i-1]$ 。顯然$a[i]$ 和 $a[i-1]$ 是不能交換了。

如果 $a[i]!=a[i-1]$ ,那麼 $f[i]=f[i-1]+f[i-2]$ 。 $a[i]$ 和 $a[i-1]$ 交換與否兩種情況累加即可。

複雜度 $O(Tnlog)$,log懶得優化了能過就行。

#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int
>pii; const int N=1e5+5; const int p=1e9+7; inline int read(){ int X=0,w=0;char ch=0; while(!isdigit(ch)){w|=ch=='-';ch=getchar();} while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } map<string,int>mp; string s; int a[N],f[N]; int main(){ int
T=read(); while(T--){ int n=read(),cnt=0; mp.clear(); f[0]=f[1]=1; for(int i=1;i<=n;i++){ cin>>s; if(!mp[s])mp[s]=++cnt; a[i]=mp[s]; if(i!=1){ if(a[i]==a[i-1])f[i]=f[i-1]; else f[i]=(f[i-1]+f[i-2])%p; } } printf("%d\n",f[n]); } return 0; }

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+歡迎訪問我的部落格:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++