题目链接: http://codeforces.com/problemset/problem/225/C
You've got an n × m pixel picture. Each pixel can be white or black. Your task is to change the colors of as few pixels as possible to obtain a barcode picture.
A picture is a barcode if the following conditions are fulfilled:
- All pixels in each column are of the same color.
- The width of each monochrome vertical line is at least x and at most y pixels. In other words, if we group all neighbouring columns of the pixels with equal color, the size of each group can not be less than x or greater than y.
The first line contains four space-separated integers n, m, x and y (1 ≤ n, m, x, y ≤ 1000; x ≤ y).
Then follow n lines, describing the original image. Each of these lines contains exactly m characters. Character "." represents a white pixel and "#" represents a black pixel. The picture description doesn't have any other characters besides "." and "#".
In the first line print the minimum number of pixels to repaint. It is guaranteed that the answer exists.
6 5 1 2 ##.#. .###. ###.. #...# .##.# ###..
11
2 5 1 1 ##### .....
5
In the first test sample the picture after changing some colors can looks as follows:
.##.. .##.. .##.. .##.. .##.. .##..
In the second test sample the picture after changing some colors can looks as follows:
.#.#. .#.#.
题意:
给出n行m列,其中 ‘#’ 为黑色,‘.’ 为白色,要求改变其中的符号,使得变成宽度为【x,y】的黑白相间的条子。
思路:
先统计#的个数,然后有两个状态方程
dp1[ i ]=max( dp2[ i - j ]+a[ i ]-a[ i - j ] , dp1[ i ] );//dp1表示涂成白的,式子表示 【前 i-j 列涂黑,j列涂白】与【前 i 列都涂白】的最优方案
dp2[ i ]=max( dp1[ i - j ]+j*n-a[ i ]+a[ i - j ],dp2[ i ]);//dp1表示涂成黑的,式子表示 【前 i-j 列涂白,j列涂黑】与【前 i 列都涂黑】的最优方案
代码如下:
#include <stdio.h>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
using namespace std;
#define N 1005
int main()
{
int n,m,x,y;
int i,j,dp1[N],dp2[N],a[N];
char ch;
while(~scanf("%d%d%d%d",&n,&m,&x,&y))
{
memset(a,0,sizeof(a));
for(i=1;i<=n;i++)
{
getchar();
for(j=1;j<=m;j++)
{
scanf("%c",&ch);
if(ch=='#')a[j]++;
}
}
a[0]=0;
for(i=1;i<=m;i++)
a[i]+=a[i-1];
memset(dp1,127,sizeof(dp1));
memset(dp2,127,sizeof(dp2));
dp1[0]=dp2[0]=0;
for(i=1;i<=m;i++)
for(j=x ; j<=y && j<=i ; j++)
{
dp1[i]=min(dp2[i-j]+a[i]-a[i-j],dp1[i]);
dp2[i]=min(dp1[i-j]+j*n-(a[i]-a[i-j]),dp2[i]);
}
printf("%d\n",min(dp1[m],dp2[m]));
}
return 0;
}