zoukankan      html  css  js  c++  java
  • 着色

    题目

     Alice是一个奇怪的画家。她想对一副有N*N个像素点组成的画进行着色,N是2的幂(1,2,4,8,16等等)。每个像素点可以着成黑色或白色。
      Alice着色方案不是唯一的,她采用以下不确定的规则:
      •如果画作只有一个像素点,那可以直接着白色或黑色;
      •否则,把画平均分成四块,然后进行以下操作:
      (1) 选择一块全部着白色;
      (2) 选择一块全部着黑色;
      (3) 把剩下的两块当作是独立的画作并采用同样的方法进行着色。
      对于每一幅画作,Alice心目中已经有一个蓝图,接下来请你帮她采用上述方法着色,要求选择跟心目中的蓝图差异最小的着色方案,当然要遵循上述的着色规则,两幅图的差异是指对应位置颜色不相同的像素点的个数。

    分析

    考虑dp,
    定义(f_{i,j,k,l}(其中0<=k<=log_{2}n)),表示对于一个矩阵,左上角的点是((i,j)),大小为((2^{k})^{2}),矩阵类型(l)(0表示全为白色的不同原图的个数,1表示全为黑色的不同原图的个数,2表示这个矩阵的最优着色方案)。
    显然,答案就是(f_{1,1,log_{2}n,2})
    那么转移也显然

    [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}=f_{i,j,k-1,a}+f_{i+2^{k-1},j,k-1,b}+f_{i,j+2^{k-1},k-1,c}+f_{i+2^{k-1},j+2^{k-1},k-1,d} ]

    其中(a、b、c、d)中,一个是0,一个是1,剩余的两个是2。

    #include <cmath>
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    const int maxlongint=2147483647;
    const int mo=1000000007;
    const int N=515;
    using namespace std;
    int a[N][N],n,m,f[N][N][11][3],mi[20],z[4][2]
    ={{1,0},{0,0},{0,1},{1,1}};
    int i,j,k;
    int solve(int p,int q,int p1,int q1)
    {
    	int t;
    	p-=1;
    	p1-=1;
    	q1-=1;
    	q-=1;
    	t=f[i+mi[k-1]*z[p][0]][j+mi[k-1]*z[p][1]][k-1][0]+
    	f[i+mi[k-1]*z[p1][0]][j+mi[k-1]*z[p1][1]][k-1][1]+
    	f[i+mi[k-1]*z[q][0]][j+mi[k-1]*z[q][1]][k-1][2]+
    	f[i+mi[k-1]*z[q1][0]][j+mi[k-1]*z[q1][1]][k-1][2];
    	if(t<f[i][j][k][2]) f[i][j][k][2]=t;
    }
    int main()
    {
    	memset(f,43,sizeof(f));
    	mi[0]=1;
    	for(i=1;i<=15;i++)
    		mi[i]=mi[i-1]*2;
    	scanf("%d",&n);
    	for(i=1;i<=n;i++)
    		for(j=1;j<=n;j++)
    		{
    			char c;
    			c=getchar();
    			while(c!='1' && c!='0')	
    				c=getchar();
    			a[i][j]=c-48;
    			f[i][j][0][0]=a[i][j];
    			f[i][j][0][1]=1-a[i][j];
    			f[i][j][0][2]=0;
    		}
    	int lo=log2(n);
    	for(k=1;k<=lo;k++)
    	{
    		for(i=1;i<=n-mi[k]+1;i++)
    			for(j=1;j<=n-mi[k]+1;j++)
    			{
    				f[i][j][k][0]=f[i][j][k-1][0]+f[i+mi[k-1]][j][k-1][0]+f[i][j+mi[k-1]][k-1][0]+f[i+mi[k-1]][j+mi[k-1]][k-1][0];
    				f[i][j][k][1]=f[i][j][k-1][1]+f[i+mi[k-1]][j][k-1][1]+f[i][j+mi[k-1]][k-1][1]+f[i+mi[k-1]][j+mi[k-1]][k-1][1];
    				solve(1,2,3,4);
    				solve(1,2,4,3);
    				solve(1,3,2,4);
    				solve(2,1,3,4);
    				solve(2,1,4,3);
    				solve(2,3,1,4);
    				solve(3,1,2,4);
    				solve(3,1,4,2);
    				solve(3,4,1,2);
    				solve(4,1,2,3);
    				solve(4,1,3,2);
    				solve(4,2,1,3);
    			}
    	}
    	printf("%d",f[1][1][lo][2]);
    }
    
    
  • 相关阅读:
    POJ 3660 Cow Contest (floyd求联通关系)
    POJ 3660 Cow Contest (最短路dijkstra)
    POJ 1860 Currency Exchange (bellman-ford判负环)
    POJ 3268 Silver Cow Party (最短路dijkstra)
    POJ 1679 The Unique MST (最小生成树)
    POJ 3026 Borg Maze (最小生成树)
    HDU 4891 The Great Pan (模拟)
    HDU 4950 Monster (水题)
    URAL 2040 Palindromes and Super Abilities 2 (回文自动机)
    URAL 2037 Richness of binary words (回文子串,找规律)
  • 原文地址:https://www.cnblogs.com/chen1352/p/9013505.html
Copyright © 2011-2022 走看看