假設你有一條長度為5的木版,初始時沒有塗過任何顏色。你希望把它的5個單位長度分別塗上紅、綠、藍、綠、紅色,用乙個長度為5的字串表示這個目標:rgbgr。 每次你可以把一段連續的木版塗成乙個給定的顏色,後塗的顏色覆蓋先塗的顏色。
例如第一次把木版塗成rrrrr,第二次塗成rgggr,第三次塗成rgbgr,達到目標。 用盡量少的塗色次數達到目標。
輸入僅一行,包含乙個長度為n的字串,即塗色目標。
字串中的每個字元都是乙個大寫字母,不同的字母代表不同顏色,相同的字母代表相同顏色。
僅一行,包含乙個數,即最少的塗色次數。
aaaaa
1
rgbgr
3
首先當這個區間長度只有1的時候,想得到這樣的顏色至少在這個位置上得粉刷一次,所以初始化dp[
i][i
]=1(
1≤i≤
n)
dp[i][i] = 1 (1\leq i \leq n)
dp[i][
i]=1
(1≤i
≤n)當區間長度大於等於2時,我們發現:
1.如果區間的兩側顏色相同的話,那麼區間兩側可以是刷子塗一次塗的,那麼我們可以利用當前長度-1的區間塗得,即dp[
i][j
]=dp
[i+1
][j]
(a[i
]==a
[j])
dp[i][j] = dp[i+1][j](a[i] ==a[j])
dp[i][
j]=d
p[i+
1][j
](a[
i]==
a[j]
)2.當區間兩側顏色不相同的話,我們可以將該區間分成兩個連續的小區間,並且當前大區間的最少粉刷次數為兩個小區間的粉刷次數之和,遍歷所有的情況,找出粉刷次數之和最小的一種分割方式,即dp[
i][j
]=mi
n(dp
[i][
j],d
p[i]
[k]+
dp[k
+1][
j])(
i≤
k dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j])(i\leq k \lt j) dp[i][ j]=m in(d p[i] [j], dp[i ][k] +dp[ k+1] [j]) (i≤k 這道題可以有乙個稍微有點公升級的公升級版(本篇文章的理解拷貝自該題),詳情點這裡:牛客 小小粉刷匠#include
using
namespace std;
char a[
1010];
int dp[
1010][
1010];
intmain()
for(
int l =
2;l<=n;l++)}
}printf
("%d\n"
,dp[1]
[n]);}
return0;
}
演算法學習 區間dp 塗色PAINT
這是一道區間dp題,題目有小錯誤,字串的長度不是5,而是小於1005的長度。定義 f i j 為區間 i,j 需要塗色最少的次數 我們可以發現這樣一件事 我們塗色盡量從最兩端的顏色開始塗,雖然無從證明,但是對該題是正確的結論。假設字串為s,當區間 i,j 兩端顏色相同時,可以先把整段區間塗成該種顏色...
sue的小球 牛客(區間dp)
sue和sandy最近迷上了乙個電腦遊戲,這個遊戲的故事發在美麗神秘並且充滿刺激的大海上,sue有一支輕便小巧的小船。然而,sue的目標並不是當乙個海盜,而是要收集空中漂浮的彩蛋,sue有乙個秘密 只要她將小船劃到乙個彩蛋的正下方,然後使用秘密 便可以在瞬間收集到這個彩蛋。然而,彩蛋有乙個魅力值,這...
區間 interval 牛客
apojacsleam喜歡陣列。他現在有乙個n個元素的陣列a,而他要對a l a r 進行m次操作 操作一 將a l a r 內的元素都加上p 操作二 將a l a r 內的元素都減去p 最後詢問a l a r 內的元素之和?請認真看題乾及輸入描述。輸入共m 3行 第一行兩個數,n,m,意義如 題目...