解析
自己對PAM的理解不夠深刻。
最優方案必然是先選擇一個偶回文串,遞歸構造出它的一半。花一步逆序,然后暴力解決剩下的。
這似乎已經依稀出現了某種dp的思路。
考慮如何更好的轉移。設計 transxtrans_xtransx? 表示長度不超過 xxx 一半的最長回文后綴,可以用類似 fail 指針的方法獲得。
那么dp就分別嘗試從后綴樹上和 trans 轉移即可。
#include<bits/stdc++.h>
using namespace std
;
#define ll long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
inline ll
read(){ll
x(0),f(1);char c
=getchar();while(!isdigit(c
)){if(c
=='-') f
=-1;c
=getchar();}while(isdigit(c
)){x
=(x
<<1)+(x
<<3)+c
-'0';c
=getchar();}return x
*f
;
}
const int N
=3e5+100;
const int mod
=19930726;
int n
;
int lst
=1,tot
=1;
int len
[N
],fa
[N
],tr
[N
][4],dp
[N
],trans
[N
],ans
;
char s
[N
];
map
<char,int>mp
;
inline void init(){len
[0]=0;len
[1]=-1;fa
[0]=1;fa
[1]=0;for(int i
=0;i
<=tot
;i
++){for(int j
=0;j
<=3;j
++) tr
[i
][j
]=0;}tot
=1;lst
=1;ans
=n
;return;
}
inline int find(int x
,int i
){while(s
[i
-len
[x
]-1]!=s
[i
]) x
=fa
[x
];return x
;
}
inline void ins(int c
,int id
){lst
=find(lst
,id
);if(!tr
[lst
][c
]){int cur
=++tot
;len
[cur
]=len
[lst
]+2;fa
[cur
]=tr
[find(fa
[lst
],id
)][c
];tr
[lst
][c
]=cur
;if(len
[cur
]<=2) trans
[cur
]=fa
[cur
];else{int o
=trans
[lst
];while(s
[id
-len
[o
]-1]!=s
[id
]||len
[o
]+2>len
[cur
]/2)o
=fa
[o
];trans
[cur
]=tr
[o
][c
];}}lst
=tr
[lst
][c
];return;
}
int q
[N
],st
,ed
;
void work(){scanf(" %s",s
+1);n
=strlen(s
+1); init();for(int i
=1;i
<=n
;i
++) ins(mp
[s
[i
]],i
);for(int i
=2;i
<=tot
;i
++) dp
[i
]=len
[i
];st
=1,ed
=0;q
[++ed
]=0;while(st
<=ed
){int now
=q
[st
++];ans
=min(ans
,n
-len
[now
]+dp
[now
]);dp
[0]=1;for(int j
=0;j
<=3;j
++){int to
=tr
[now
][j
];if(!to
) continue;dp
[to
]=min(dp
[now
]+1,dp
[trans
[to
]]+len
[to
]/2-len
[trans
[to
]]+1);q
[++ed
]=to
;}}printf("%d\n",ans
);
}
signed main(){#ifndef ONLINE_JUDGE#endifmp
['A']=0;mp
['T']=1;mp
['C']=2;mp
['G']=3;int T
=read();while(T
--) work();return 0;
}
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的洛谷P4762: [CERC2014]Virus synthesis(PAM)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。