題目傳送門
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分。
當初搞完特殊情況之後就在想一般情況,然後就在想怎麼給每個木板分配粉刷次數t。如果把t拆成n個正整數的話,感覺這本身就是乙個複雜度很高的爆搜2333。然後就不知道怎麼處理多塊木板了。#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;
}
結果正解是多次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 次,他最多能正確粉刷多少格仔?乙個格仔如果未被粉刷或者被粉刷錯顏色,就算錯誤粉刷...