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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

鏈接:

題目描述

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

輸入描述:

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

輸出描述:

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

示例1
輸入

3 6 3 111111 000000 001100

輸出

16

題意:

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

題解:

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

二維dp

就是一個分組背包求解
預處理每塊木板的最優解
因為木板只有0或1,所以我們將1統計出來,剩下的就是0
可以用到前綴和來統計1的數量
pre[i]表示前i塊中1的數量
dp [ i ] [ j ] 表示前i塊木板粉刷j次最多可以刷的格子數

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

代碼略

四維dp

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

如果涂的是當前木板第一段(也就是j=1),就要接著上一個木板轉移:
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塊木板的第一段是由當前木板的顏色加上上塊木板的最大值情況
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])

如果不是當前木板第一段,那就是同塊木板的上一段承接而來
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)或藍(1)哪個最多
dp[n][m][t][0/1]
看到一個大佬用的滾動數組壓維(秒啊)

滾動數組壓維版代碼

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');}

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。