日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

牛客网 【每日一题】[SCOI2009]粉刷匠

發(fā)布時(shí)間:2023/12/3 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 牛客网 【每日一题】[SCOI2009]粉刷匠 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

鏈接:

題目描述

windy有 N 條木板需要被粉刷。 每條木板被分為 M 個(gè)格子。 每個(gè)格子要被刷成紅色或藍(lán)色。
windy每次粉刷,只能選擇一條木板上一段連續(xù)的格子,然后涂上一種顏色。 每個(gè)格子最多只能被粉刷一次。 如果windy只能粉刷 T
次,他最多能正確粉刷多少格子? 一個(gè)格子如果未被粉刷或者被粉刷錯(cuò)顏色,就算錯(cuò)誤粉刷。

輸入描述:

輸入文件paint.in第一行包含三個(gè)整數(shù),N M T。 接下來有N行,每行一個(gè)長度為M的字符串,'0’表示紅色,'1’表示藍(lán)色。

輸出描述:

輸出文件paint.out包含一個(gè)整數(shù),最多能正確粉刷的格子數(shù)。

示例1
輸入

3 6 3 111111 000000 001100

輸出

16

題意:

n個(gè)木板,有m個(gè)格子,能粉刷t次,每次可以粉刷連續(xù)的一段,問最多能正確粉刷多少個(gè)格子?

題解:

怎么涂才最大化?其實(shí)全涂最好,為什么?反正涂錯(cuò)沒懲罰,涂對(duì)就算賺,但是我們只能涂t次,所以就是t行涂滿
dp的做法
有二維dp和四維dp的做法

二維dp

就是一個(gè)分組背包求解
預(yù)處理每塊木板的最優(yōu)解
因?yàn)槟景逯挥?或1,所以我們將1統(tǒng)計(jì)出來,剩下的就是0
可以用到前綴和來統(tǒng)計(jì)1的數(shù)量
pre[i]表示前i塊中1的數(shù)量
dp [ i ] [ j ] 表示前i塊木板粉刷j次最多可以刷的格子數(shù)

我們根據(jù)題意可以得到轉(zhuǎn)移方程
pree=pre[r]-pre[l]//表示區(qū)間l到r之間1的數(shù)量
f [ r] [ j ] = max ( f [ r ] [ j ] [ , f [ l ] [ j-1 ] + max ( pree ,r-l-pree))
怎么理解?
前r塊的木板粉刷j次,是前l(fā)塊木板粉刷j-1次,再加上l與r之間的最大數(shù)(這個(gè)最大數(shù)是指1和0哪個(gè)出現(xiàn)的次數(shù)最多,這樣就粉刷數(shù)量多的那個(gè)顏色)

代碼略

四維dp

dp [ i ] [ j ] [ k ] [ 1 / 0] 表示前i條第j段涂了k次,涂成紅(0)或藍(lán)(1)的最多格子數(shù)

如果涂的是當(dāng)前木板第一段(也就是j=1),就要接著上一個(gè)木板轉(zhuǎn)移:
dp[i][j][k][0]=if(a[i][j]==′0 ′)+max(dp[i?1][m][k?1][0],dp[i?1][m][k?1][1])
第i塊木板的第一段是由當(dāng)前木板的顏色加上上塊木板的最大值情況
dp[i][j][k][1] = if(a[i][j] == ‘1’)+max(dp[i-1][m][k-1][0],dp[i-1][m][k-1][1])

如果不是當(dāng)前木板第一段,那就是同塊木板的上一段承接而來
dp[i][j][k][0]=if(a[i][j]== ′0′ ) + max(dp[i][j?1][k][0],dp[i][j?1][k?1][1])

dp[i][j][k][1] = if(a[i][j] == ’ 1 ') + max(dp[i][j-1][k-1][0],dp[i][j-1][k][1])
本段木板顏色直接承接前一段的最大值
答案就是看紅(0)或藍(lán)(1)哪個(gè)最多
dp[n][m][t][0/1]
看到一個(gè)大佬用的滾動(dòng)數(shù)組壓維(秒啊)

滾動(dòng)數(shù)組壓維版代碼

for (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++)for (int k = 1; k <= t; k++){if (j == 1)dp[i & 1][j][k][1] = max(dp[(i - 1) & 1][m][k - 1][0], dp[(i - 1) & 1][m][k - 1][1]) + (a[i][j] == 1 + '0');elsedp[i & 1][j][k][1] = max(dp[i & 1][j - 1][k][1], dp[i & 1][j - 1][k - 1][1 ^ 1]) + (a[i][j] == 1 + '0');if (j == 1)dp[i & 1][j][k][0] = max(dp[(i - 1) & 1][m][k - 1][0], dp[(i - 1) & 1][m][k - 1][1]) + (a[i][j] == 0 + '0');elsedp[i & 1][j][k][0] = max(dp[i & 1][j - 1][k][0], dp[i & 1][j - 1][k - 1][0 ^ 1]) + (a[i][j] == 0 + '0');}

總結(jié)

以上是生活随笔為你收集整理的牛客网 【每日一题】[SCOI2009]粉刷匠的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。