题目描述
AliceAliceAlice是一个奇怪的画家。她想对一副有N∗NN*NN∗N个像素点组成的画进行着色,NNN是222的幂(1,2,4,8,16(1,2,4,8,16(1,2,4,8,16等等)))。每个像素点可以着成黑色或白色。
AliceAliceAlice着色方案不是唯一的,她采用以下不确定的规则:
如果画作只有一个像素点,那可以直接着白色或黑色;
否则,把画平均分成四块,然后进行以下操作:
(1)(1)(1) 选择一块全部着白色;
(2)(2)(2) 选择一块全部着黑色;
(3)(3)(3) 把剩下的两块当作是独立的画作并采用同样的方法进行着色。
对于每一幅画作,AliceAliceAlice心目中已经有一个蓝图,接下来请你帮她采用上述方法着色,要求选择跟心目中的蓝图差异最小的着色方案,当然要遵循上述的着色规则,两幅图的差异是指对应位置颜色不相同的像素点的个数。
题目解析
我们设F[i][j][k][w]F[i][j][k][w]F[i][j][k][w]为以i,ji,ji,j坐标为起点扩大的大小为2k2^k2k的正方形,l=0l=0l=0表示当前正方形全白,111全黑,222则第三种操作,时的最小差异值。
那么,
F[i][j][k][0]=F[i][j][k][0]=F[i][j][k][0]=当前正方形平均分成四份时全白时的差异值和
F[i][j][k][1]=F[i][j][k][1]=F[i][j][k][1]=当前正方形平均分成四份时全黑时的差异值和
F[i][j][k][2]F[i][j][k][2]F[i][j][k][2]则有121212种可能,取最小值就可以了。
一个正方形平均分成四份,一份填白,一份填黑,另两份为第三种操作。可以算出刚好121212种可能
最后输出F[1][1][log2(n)][2]F[1][1][log2(n)][2]F[1][1][log2(n)][2]就可以了。
代码
#include<bits/stdc++.h>
using namespace std;
int n;
int a[600][600],f[515][515][11][3],p[20];
char c;
int main()
{
p[0]=1;
for(int i=1;i<=10;i++) p[i]=p[i-1]*2;
cin>>n;
memset(f,0x3f,sizeof(f));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>c;
a[i][j]=c-'0';
f[i][j][0][0]=a[i][j];
f[i][j][0][1]=1-a[i][j];
f[i][j][0][2]=0;
}
}
for(int k=1;k<=log2(n);k++)
for(int i=1;i<=n-p[k]+1;i++)
for(int j=1;j<=n-p[k]+1;j++)
{
f[i][j][k][0]=f[i][j][k-1][0]+f[i+p[k-1]][j][k-1][0]+f[i][j+p[k-1]][k-1][0]+f[i+p[k-1]][j+p[k-1]][k-1][0];
f[i][j][k][1]=f[i][j][k-1][1]+f[i+p[k-1]][j][k-1][1]+f[i][j+p[k-1]][k-1][1]+f[i+p[k-1]][j+p[k-1]][k-1][1];
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][0]+f[i+p[k-1]][j][k-1][1]+f[i][j+p[k-1]][k-1][2]+f[i+p[k-1]][j+p[k-1]][k-1][2]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][0]+f[i+p[k-1]][j][k-1][2]+f[i][j+p[k-1]][k-1][1]+f[i+p[k-1]][j+p[k-1]][k-1][2]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][0]+f[i+p[k-1]][j][k-1][2]+f[i][j+p[k-1]][k-1][2]+f[i+p[k-1]][j+p[k-1]][k-1][1]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][1]+f[i+p[k-1]][j][k-1][0]+f[i][j+p[k-1]][k-1][2]+f[i+p[k-1]][j+p[k-1]][k-1][2]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][1]+f[i+p[k-1]][j][k-1][2]+f[i][j+p[k-1]][k-1][0]+f[i+p[k-1]][j+p[k-1]][k-1][2]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][1]+f[i+p[k-1]][j][k-1][2]+f[i][j+p[k-1]][k-1][2]+f[i+p[k-1]][j+p[k-1]][k-1][0]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][2]+f[i+p[k-1]][j][k-1][0]+f[i][j+p[k-1]][k-1][1]+f[i+p[k-1]][j+p[k-1]][k-1][2]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][2]+f[i+p[k-1]][j][k-1][0]+f[i][j+p[k-1]][k-1][2]+f[i+p[k-1]][j+p[k-1]][k-1][1]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][2]+f[i+p[k-1]][j][k-1][1]+f[i][j+p[k-1]][k-1][0]+f[i+p[k-1]][j+p[k-1]][k-1][2]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][2]+f[i+p[k-1]][j][k-1][1]+f[i][j+p[k-1]][k-1][2]+f[i+p[k-1]][j+p[k-1]][k-1][0]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][2]+f[i+p[k-1]][j][k-1][2]+f[i][j+p[k-1]][k-1][0]+f[i+p[k-1]][j+p[k-1]][k-1][1]);
f[i][j][k][2]=min(f[i][j][k][2],f[i][j][k-1][2]+f[i+p[k-1]][j][k-1][2]+f[i][j+p[k-1]][k-1][1]+f[i+p[k-1]][j+p[k-1]][k-1][0]);
}
int A=log2(n);
cout<<f[1][1][A][2];
}