假設你有一條長度為 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...