題解 CQOI2007 塗色

2021-10-07 16:15:37 字數 2083 閱讀 5834

假設你有一條長度為 55 的木版,初始時沒有塗過任何顏色。你希望把它的 5

55個單位長度分別塗上紅、綠、藍、綠、紅色,用乙個長度為5

55的字串表示這個目標:rgbgr

每次你可以把一段連續的木版塗成乙個給定的顏色,後塗的顏色覆蓋先塗的顏色。例如第一次把木版塗成rrrrr,第二次塗成rgggr,第三次塗成rgbgr,達到目標。

用盡量少的塗色次數達到目標。

輸入僅一行,包含乙個長度為n

nn的字串,即塗色目標。字串中的每個字元都是乙個大寫字母,不同的字母代表不同顏色,相同的字母代表相同顏色。

僅一行,包含乙個數,即最少的塗色次數。

aaaaa
1
rgbgr
3
40

%40\%

40% 的資料滿足1≤n

≤10

1\le n\le10

1≤n≤10

。100

%100\%

100%

的資料滿足1≤n

≤50

1\le n\le 50

1≤n≤50

。我們把問題抽象成為乙個長度為n

nn的字串s

ss,字串中每種字母代表一種顏色。 用 dp[

x][y

]dp[x][y]

dp[x][

y]表示讓區間 [x,

y]

[x, y]

[x,y

] 滿足條件的最小次數。然後我們按照區間長度從小到大列舉每乙個區間。

我們可以先把[x,

y]

[x, y]

[x,y

]整體塗成乙個顏色,然後再去處理[x+

1,y−

1]

[x + 1, y - 1]

[x+1,y

−1]。對應的轉移為:

dp[x]

[y]=

min(dp[x]

[y],dp[x+1]

[y−1]+

1)

或者對於區間[x,

y−1]

[x, y - 1]

[x,y−1

],因為x

xx是最邊上的位置,所以最優情況下,一定可以第乙個塗x

xx位置,這樣我們可以讓這次塗色延長到y

yy,這樣實際上y

yy就順帶滿足條件了,區間[x+

1,y]

[x + 1, y]

[x+1,y

]也是同樣原理,對應的轉移為:

dp[x]

[y]=

min(dp[x]

[y−1

],dp[x+1]

[y])

那麼實際上x

xx和y

yy沒有關係,所以我們可以把區間分成兩部分來完成,一部分包含 x

xx,一部分包含y

yy。對應的轉移為:

∀ x≤k[y]=

min(dp[x]

[y],dp[x]

[k]+dp[k+1]

[y])

按照剛才的分析,可以得到如下**:

#include

#include

#include

#include

using

namespace std;

const

int inf =

0x3f3f3f3f

;int dp[55]

[55];

intmain()

for(

int l=

2;l<=s.

size()

;l++

)else

}else}}

} cout<[s.size()

-1]

}

題解 CQOI2007 餘數求和

考慮到這個等式 a bmod b a b lfloor frac rfloor 所以我們可以得到 begin ans sum k bmod i sum k i lfloor frac rfloor end 我們可以證得若 lfloor frac rfloor 是相同的,則對應的b所取得的區間必然是連...

CQOI2007 餘數求和

求 ans k 1 k 2 k n 這題目應該算是數論裡比較簡單的了 求 ni 1 kmod i i 1nkm od i我們知道 a b a b a b 即 ni 1 kmod i n i 1 k i k i n k ni 1 i k i i 1nkm odi i 1 n k i k i n k i...

CQOI2007 餘數求和

題面 這道題用到了數論分塊 首先什麼是數論分塊 顧名思義就是分塊在數論上的應用 不過非常神奇的一點是你如果不會分塊但你還是可以會數論分塊的 所求為 i 1nkm od i sum k mod i i 1 n kmod i將這個式子改為 i 1nk i ki sum k i left lfloor f...