前言
每次做出來什麼本來做不出的題目,就忍不住記錄一下。不過大多時候隔幾天來看,就發現,啊,我當時只是做了一道這麼弱智的題目呀,哈哈。字首和確實不算太難。。
傳送門題目大意:
給你乙個字串只含g和r,求乙個最長子串長度,使得兩個字元的長度相等。(給的字串長小於1e6)
如:grggrg
答案是:4。
思路
題目中字串很長,暴力列舉顯然不可能。
但我們仔細一看,發現不過只有兩個字元g和h。我們令g為1,令r為-1,那麼gr的值就為0,這顯然是乙個可行的子串。
那再看grggrg,我們開乙個a陣列記錄前i個字元的值,那麼
a[0]=0,a[1]=1,a[2]=0,a[3]=1.a[4]=2,a[5]=1,a[6]=2。
觀察可得1~3是乙個可行的子串(不包括1)
1~5同樣可行(不包括1)
也就是說,當他們對應的a陣列值相等時,中間的串必定可行,因為中間的串沒有引起值的變化,那麼g和r相等。
那接下來我們該怎麼做呢?
我們可以用2個for迴圈列舉陣列a,找出值相等並且下標相差最大的兩個點即為最大子串,但這樣複雜度過高。
for(int i=0;i但是新的問題又來了,a[i+1]可能是負數,陣列可沒有負數的下標!其實這並不難,我們把dp的第一維擴大一倍,把中間的下標當作原來的下標零來使用,像這樣:
//maxn=10000007
for(int i=0;i完整**:
#include using namespace std;
const int maxn=1000009;
int a[2*maxn];
string str1;
int dp[maxn*2+9][3];
int main()
{ cin>>str1;
for(int i=0;i<=maxn*2-5;i++)
dp[i][1]=100000000;//為min作預處理
dp[maxn+1][1]=0;//這裡可以把maxn+1看作原來的下標0
for(int i=0;i感謝dalao過目!
洛谷 P2697 寶石串
將紅色的設定為 1,綠色的為1,統計字首和sum,如果sum i sum j 則說明i j是乙個穩定的區間 因為答案要求最大,所以我們要記錄每個sum值的最左端點 也就是哪個位置第一次出現某個sum值 每當遇到某個sum值,便利用最左端點求出區間長度,更新答案 吐槽 洛谷標籤裡是個dp,我就沒往其他...
洛谷P2697 寶石串
題目鏈結 題目大意 給乙個只有 texttt 和 texttt 的字串,求乙個 texttt 和 texttt 數量相同的區間,輸出這個區間的最大長度。題解 1.暴力 把所有 texttt 標記為 1 把所有 texttt 標記為 1 求一下字首和陣列 s 二重迴圈列舉左端點和右端點 i j 如果 ...
bzoj 4976 寶石鑲嵌(貪心 高位字首和)
傳送門biu 當n k 16時,每一位上的1都可以出現,只需要考慮每位是否有1即可。剩下的情況n最大只有115 資料範圍瞬間變得友善了 令f state 代表組合出state最少需要多少個數,跑揹包即可。然後再將f state 更新成組合出包含state這個集合的數最少需要多少個數,列舉每個狀態的子...