HDU - 5371 Hotaru's problem(马拉车+暴力)
生活随笔
收集整理的這篇文章主要介紹了
HDU - 5371 Hotaru's problem(马拉车+暴力)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點擊查看
題目大意:給出n個數組成的數列,現在規定一種結構滿足以下條件:
現在問數列中最長的可以組成該結構的字串的長度
題目分析:對于題目中的條件,我們換句話來解釋,還是三個部分,顯然第一個部分和第二個部分可以組成回文串,第二個部分可以和第三個部分組成回文串,而且組成的回文串還都是偶回文串,既然涉及到了字串和回文串,我們可以先用馬拉車跑一下以每個位置為終點的回文串長度,此后就可以暴力維護答案了,既然是要求兩個回文串,且必須滿足其中間有交集,則只需滿足:
如果滿足上述三個條件,那么必然可以構造出一種題目要求的數列,且長度為x*3,如此暴力維護一下最大值就是答案了
不得不說,這個題我是不太敢暴力的,但加上了最優性剪枝,以及適當的break之后,其實暴力起來的時間復雜度遠遠小于n*n,反而更接近O(n)
代碼:
#include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cstring> #include<algorithm> #include<stack> #include<queue> #include<map> #include<set> #include<sstream> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=2e5+100;int a[N],p[N],n;void Manacher() {p[0]=1;int id=0,mmax=0;for(int i=1;i<n;i++){if(i<mmax)p[i]=min(mmax-i,p[2*id-i]);elsep[i]=1;while(a[i-p[i]]==a[i+p[i]])p[i]++;if(i+p[i]>mmax){mmax=i+p[i];id=i;}p[i]--;//這里減一代表的是不算當前位置可以向左或向右擴展多少個單位 } } int main() { // freopen("input.txt","r",stdin); // ios::sync_with_stdio(false);int w;cin>>w;int kase=0;while(w--){int nn;scanf("%d",&nn);n=0;a[n++]=-1;while(nn--){a[n++]=0;scanf("%d",&a[n++]);}a[n++]=0;a[n++]=-1;Manacher();int ans=0;for(int i=1;i<n;i+=2)//枚舉第一個回文串的中點,因為要跳過'#',所以每次加二for(int j=i+p[i];j-i>ans;j-=2)//枚舉第二個回文串的中點,同理每次減二 if(j-i<=p[j]){ans=max(ans,j-i);break;}printf("Case #%d: %d\n",++kase,ans/2*3);}return 0; }?
總結
以上是生活随笔為你收集整理的HDU - 5371 Hotaru's problem(马拉车+暴力)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中石油训练赛 - DNA(字符串哈希)
- 下一篇: HDU - 5187 zhx's con