dp SCOI2009粉刷匠 紀中集訓提高B組

2021-09-26 02:04:31 字數 2538 閱讀 2713

題目傳送門

jzoj1035

windy有 n 條木板需要被粉刷。

每條木板被分為 m 個格仔。

每個格仔要被刷成紅色或藍色。

windy每次粉刷,只能選擇一條木板上一段連續的格仔,然後塗上一種顏色。

每個格仔最多只能被粉刷一次。

如果windy只能粉刷 t 次,他最多能正確粉刷多少格仔?

乙個格仔如果未被粉刷或者被粉刷錯顏色,就算錯誤粉刷。

第一行包含三個整數,n m t。

接下來有n行,每行乙個長度為m的字串,'0』表示紅色,'1』表示藍色。

輸出乙個整數,表示最多能正確粉刷的格仔數。

3 6 3

111111

000000

001100

100%的資料,滿足 1 <= n,m <= 50 ; 0 <= t <= 2500 。

考場上第一眼以為是貪心。

後面發現不對,覺得是dp,但是它分了很多塊木塊就不知道怎麼處理。(如果是一塊整的就大概知道怎麼做)

考場上只做了特殊情況,只有10分。

#include

#include

#include

using

namespace std;

#define n 55

#define ll long long

#define inf 0x3f3f3f3f

int n,m,t;

struct nodea[n]

;int tmp[n]

;bool

cmp(

int p,

int q)

intmain()

}if(t<=n)

if(t>=seg)

return0;

}

當初搞完特殊情況之後就在想一般情況,然後就在想怎麼給每個木板分配粉刷次數t。如果把t拆成n個正整數的話,感覺這本身就是乙個複雜度很高的爆搜2333。然後就不知道怎麼處理多塊木板了。

結果正解是多次dp,對嘛,不知道怎麼處理多塊木板的話,就把每塊木板當成乙個整體再dp一次。

評講說是分組揹包,把每塊木板當成乙個整體再dp一次那裡確實是分組揹包,因為每塊木板塗的次數是相互衝突的。(不能既塗1次,又塗2次)

感覺這種思想很奇妙,就像是眼光逐漸從區域性到整體,先dp每塊木板在塗不同次數下的最優值,再把這些木板當成整體,來分配總的t次粉刷。

考場上還貪心地想到最好是相同顏色的肯定是要只用一次刷子(如上程式),但是dp的時候這麼寫的話細節處理很繁瑣,容易寫錯,所以把每個格仔當成乙個個體就好。

#include

#include

#include

#include

using

namespace std;

#define n 55

#define m 2005

int f[n]

[m],g[n]

[m][n]

,sum[n]

[m];

int n,m,t;

/*f[i][j]:前i行塗j次的最大正確格仔數

g[i][j][k]:第i行塗j次 塗到前k個格仔的最大數量

//(注意是第i行 真正約束狀態的是j&k 有個i只是因為它有很多塊木板 f才是連線各個木板關係的)

sum[i][j]:第i行前j個格仔中1的數量

*/int

main()

for(

int i=

1;i<=n;i++

)for

(int j=

1;j<=m;j++

)for

(int k=j;k<=m;k++

)//塗j次 至少都會塗到j個

for(

int q=j-

1;q<=k-

1;q++

)//列舉塗j-1次時塗到的是**

g[i]

[j][k]

=max

(g[i]

[j][k]

,g[i]

[j-1

][q]

+max

(sum[i]

[k]-sum[i]

[q],k-q/*總格仔數*/

-(sum[i]

[k]-sum[i]

[q])))

;for

(int i=

1;i<=n;i++

)for

(int j=

1;j<=t;j++

)for

(int k=

0;k<=

min(j,m)

;k++

)//在當前這一行塗k次

f[i]

[j]=

max(f[i]

[j],f[i-1]

[j-k]

+g[i]

[k][m]);

printf

("%d\n"

,f[n]

[t])

;return0;

}

洛谷 4158 SCOI2009 粉刷匠

題目描述 windy有 n 條木板需要被粉刷。每條木板被分為 m 個格仔。每個格仔要被刷成紅色或藍色。windy每次粉刷,只能選擇一條木板上一段連續的格仔,然後塗上一種顏色。每個格仔最多只能被粉刷一次。如果windy只能粉刷 t 次,他最多能正確粉刷多少格仔?乙個格仔如果未被粉刷或者被粉刷錯顏色,就...

題解 lg4158 SCOI2009 粉刷匠

給 n 條每條被劃分成 m 個格仔的木板每個格仔刷顏色,每一次刷只能刷一條木板連續的一段,且每乙個格仔最多只能粉刷一次,一共只能刷 t 次,問能夠正確的刷多少格仔.有乙個很顯然的性質,就是一條木板要是要塗就一定會塗滿但baka fpjo顯然沒有注意到這一點 且還有每乙個格仔最多只能粉刷一次 然後就很...

SCOI2009 粉刷匠(分組揹包)

windy有 n 條木板需要被粉刷。每條木板被分為 m 個格仔。每個格仔要被刷成紅色或藍色。windy每次粉刷,只能選擇一條木板上一段連續的格仔,然後塗上一種顏色。每個格仔最多只能被粉刷一次。如果windy只能粉刷 t 次,他最多能正確粉刷多少格仔?乙個格仔如果未被粉刷或者被粉刷錯顏色,就算錯誤粉刷...