程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> bzoj1296【SCOI2009】粉刷匠

bzoj1296【SCOI2009】粉刷匠

編輯:C++入門知識

bzoj1296【SCOI2009】粉刷匠


Description

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

Input

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

Output

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

Sample Input

3 6 3
111111
000000
001100

Sample Output

16

HINT

30%的數據,滿足 1 <= N,M <= 10 ; 0 <= T <= 100 。 100%的數據,滿足 1 <= N,M <= 50 ; 0 <= T <= 2500 。

Source

這道題做法是兩次DP。

可以發現不同的木板是相互獨立,互相無影響的。所以我們可以O(n^3)暴力DP計算出每一條木板,粉刷j次最多能正確粉刷的數量。然後對於不同的木板再用一次DP計算答案。

#include
#include
#include
#include
#include
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
using namespace std;
int n,m,t,ans=0;
int sum[55],f[55][55],g[55][2505];
char s[55];
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int main()
{
	n=read();m=read();t=read();
	F(i,1,n)
	{
		scanf("%s",s+1);
		F(j,1,m) sum[j]=sum[j-1]+(s[j]=='1');
		F(k,1,m) F(j,1,m)
		{
			f[j][k]=0;
			F(l,0,j-1)
			{
				int tmp=sum[j]-sum[l];
				f[j][k]=max(f[j][k],f[l][k-1]+max(tmp,j-l-tmp));
			}
		}
		F(j,1,t) F(k,1,min(j,m)) g[i][j]=max(g[i][j],g[i-1][j-k]+f[m][k]);
	}
	F(i,1,t) ans=max(ans,g[n][i]);
	printf("%d\n",ans);
	return 0;
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved