Problem
Description
Alice是一个奇怪的画家。她想对一副有N*N个像素点组成的画进行着色,N是2的幂(1,2,4,8,16等等)。每个像素点可以着成黑色或白色。
Alice着色方案不是唯一的,她采用以下不确定的规则:
•如果画作只有一个像素点,那可以直接着白色或黑色;
•否则,把画平均分成四块,然后进行以下操作:
(1) 选择一块全部着白色;
(2) 选择一块全部着黑色;
(3) 把剩下的两块当作是独立的画作并采用同样的方法进行着色。
对于每一幅画作,Alice心目中已经有一个蓝图,接下来请你帮她采用上述方法着色,要求选择跟心目中的蓝图差异最小的着色方案,当然要遵循上述的着色规则,两幅图的差异是指对应位置颜色不相同的像素点的个数。
Input
输入第一行包含整数N(1<=N<=512),表示画作的尺寸为N*N,N保证是2的幂。接下来N行每行包含N个0或1,描述Alice心目中的蓝图,0表示白色,1表示黑色。
Output
第一行输出最小的差异是多少。
Sample Input
输入1:
4
0001
0001
0011
1110
输入2:
4
1111
1111
1111
1111
输入3:
8
01010001
10100011
01010111
10101111
01010111
10100011
01010001
10100000
Sample Output
输出1:
1
输出2:
6
输出3:
16
Data Constraint
50%的数据N<=8
Solution
这道题我本来用暴力,但发现有问题TOT。正解直接DP,不过有一点恶心。
我们设
Fi,j,k,l
为以i,j为起点扩大的大小为
2k
的矩阵,l=0表示当前矩阵全白,1全黑,2随便搞搞。那么
Fi,j,k,2 则有12种可能(你们枚举一下就知道了),取最大值就可以了。
(由于这条方程太长,我不打出来了,如果想看的就看看我的标)
最后输出 F1,1,log2(n),2 就可以了。
Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#define N 520
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
int a[N][N],f[N][N][12][3],i,j,k,n,mn,ans,_2[12];
char ch;
int main()
{
freopen("1429_1.in","r",stdin);
_2[0]=1;
fo(i,1,12) _2[i]=_2[i-1]*2;
scanf("%d\n",&n);
memset(f,127,sizeof(f));
fo(i,1,n)
{
fo(j,1,n)
{
scanf("%c",&ch);
a[i][j]=ch-48;
f[i][j][0][0]=a[i][j];
f[i][j][0][1]=1-a[i][j];
f[i][j][0][2]=0;
}
scanf("\n");
}
fo(k,1,log2(n))
fo(i,1,n-_2[k]+1)
fo(j,1,n-_2[k]+1)
{
f[i][j][k][0]=f[i][j][k-1][0]+f[i+_2[k-1]][j][k-1][0]+f[i][j+_2[k-1]][k-1][0]+f[i+_2[k-1]][j+_2[k-1]][k-1][0];
f[i][j][k][1]=f[i][j][k-1][1]+f[i+_2[k-1]][j][k-1][1]+f[i][j+_2[k-1]][k-1][1]+f[i+_2[k-1]][j+_2[k-1]][k-1][1];
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][0]+f[i+_2[k-1]][j][k-1][1]+f[i][j+_2[k-1]][k-1][2]+f[i+_2[k-1]][j+_2[k-1]][k-1][2]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][0]+f[i+_2[k-1]][j][k-1][2]+f[i][j+_2[k-1]][k-1][1]+f[i+_2[k-1]][j+_2[k-1]][k-1][2]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][0]+f[i+_2[k-1]][j][k-1][2]+f[i][j+_2[k-1]][k-1][2]+f[i+_2[k-1]][j+_2[k-1]][k-1][1]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][1]+f[i+_2[k-1]][j][k-1][0]+f[i][j+_2[k-1]][k-1][2]+f[i+_2[k-1]][j+_2[k-1]][k-1][2]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][1]+f[i+_2[k-1]][j][k-1][2]+f[i][j+_2[k-1]][k-1][0]+f[i+_2[k-1]][j+_2[k-1]][k-1][2]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][1]+f[i+_2[k-1]][j][k-1][2]+f[i][j+_2[k-1]][k-1][2]+f[i+_2[k-1]][j+_2[k-1]][k-1][0]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][2]+f[i+_2[k-1]][j][k-1][0]+f[i][j+_2[k-1]][k-1][1]+f[i+_2[k-1]][j+_2[k-1]][k-1][2]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][2]+f[i+_2[k-1]][j][k-1][0]+f[i][j+_2[k-1]][k-1][2]+f[i+_2[k-1]][j+_2[k-1]][k-1][1]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][2]+f[i+_2[k-1]][j][k-1][1]+f[i][j+_2[k-1]][k-1][0]+f[i+_2[k-1]][j+_2[k-1]][k-1][2]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][2]+f[i+_2[k-1]][j][k-1][1]+f[i][j+_2[k-1]][k-1][2]+f[i+_2[k-1]][j+_2[k-1]][k-1][0]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][2]+f[i+_2[k-1]][j][k-1][2]+f[i][j+_2[k-1]][k-1][0]+f[i+_2[k-1]][j+_2[k-1]][k-1][1]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][2]+f[i+_2[k-1]][j][k-1][2]+f[i][j+_2[k-1]][k-1][1]+f[i+_2[k-1]][j+_2[k-1]][k-1][0]);
}
mn=log2(n);
printf("%d",f[1][1][mn][2]);
}
——2016.7.13