字首和(P2697 寶石串)

2021-10-02 06:34:46 字數 1118 閱讀 4872

前言

每次做出來什麼本來做不出的題目,就忍不住記錄一下。不過大多時候隔幾天來看,就發現,啊,我當時只是做了一道這麼弱智的題目呀,哈哈。字首和確實不算太難。。

傳送門題目大意

給你乙個字串只含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這個集合的數最少需要多少個數,列舉每個狀態的子...