塗色PAINT 牛客(區間dp,基礎)

2021-09-25 17:24:06 字數 1679 閱讀 5877

假設你有一條長度為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,意義如 題目...