1296: [SCOI2009]粉刷匠
阿新 • • 發佈:2018-11-20
%s 一個 enter esp 選擇 set ref ros spa Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 2752 Solved: 1591
[Submit][Status][Discuss]
111111
000000
001100
Submit: 2752 Solved: 1591
[Submit][Status][Discuss]
Description
windy有 N 條木板需要被粉刷。 每條木板被分為 M 個格子。 每個格子要被刷成紅色或藍色。 windy每次粉刷,只能選擇一條木板上一段連續的格子,然後塗上一種顏色。 每個格子最多只能被粉刷一次。 如果windy只能粉刷 T 次,他最多能正確粉刷多少格子? 一個格子如果未被粉刷或者被粉刷錯顏色,就算錯誤粉刷。
Input
輸入文件paint.in第一行包含三個整數,N M T。 接下來有N行,每行一個長度為M的字符串,‘0‘表示紅色,‘1‘表示藍色。
Output
輸出文件paint.out包含一個整數,最多能正確粉刷的格子數。
Sample Input
3 6 3111111
000000
001100
Sample Output
16HINT
30%的數據,滿足 1 <= N,M <= 10 ; 0 <= T <= 100 。 100%的數據,滿足 1 <= N,M <= 50 ; 0 <= T <= 2500 。
註意,每個格子只能塗一次
先暴力統計f[k][j],前k個格子塗j次,最多能塗幾個
然後背包動規
1 #include<iostream> 2#include<cstdio> 3 #include<cstring> 4 using namespace std; 5 6 char ch[60]; 7 int n,m,t,ans; 8 int sum[60],f[60][60],g[60][2600]; 9 10 int main() 11 { 12 scanf("%d%d%d",&n,&m,&t); 13 for(int i=1;i<=n;i++) 14 { 15 memset(sum,0,sizeof(sum));16 memset(f,0,sizeof(f)); 17 scanf("%s",ch+1); 18 for(int j=1;j<=m;j++) 19 sum[j]=sum[j-1]+(ch[j]==‘1‘); 20 for(int j=1;j<=m;j++) 21 for(int k=1;k<=m;k++) 22 { 23 for(int l=0;l<k;l++) 24 f[k][j]=max(f[k][j],f[l][j-1]+max(sum[k]-sum[l],(k-l)-(sum[k]-sum[l]))); 25 } 26 for(int j=1;j<=t;j++) 27 for(int k=1;k<=min(j,m);k++) 28 g[i][j]=max(g[i][j],g[i-1][j-k]+f[m][k]); 29 } 30 for(int i=1;i<=t;i++) 31 ans=max(ans,g[n][i]); 32 printf("%d\n",ans); 33 return 0; 34 }
1296: [SCOI2009]粉刷匠