sgu-262 Symbol Recognition

来源:互联网 发布:云计算安全关键技术 编辑:程序博客网 时间:2024/05/16 06:17

题目大意:

KNM01矩阵(1<=N,M<=10,2<=K<=6),保证两两不同,然后要你从NM矩阵中选出最少的位置,使得仅靠这些位置就能区分这K个矩阵。
 
 
 

解题思路:

我们观察到K的范围,发现如果我们将所有矩阵两两是否可以区分的信息存储下来需要的空间是2K(K1)2,是可以承受的,然后我们逐格dpF[i][j][G]表示考虑到了第(i,j)并且区分状态是G时所需的最小的选取数,然后我们可以预处理出对于选取(i,j)可以区分那几对矩阵。
所以最后的答案就是F[N][M][2K(K1)21]
 
 
 

AC代码:

#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <algorithm>#include <iostream>using namespace std;int N,M;int K;int ch[10][20][20]={{{0}}};int change[20][20]={{0}};int F[33000]={0};bool Matrix[33000][11][11]={{{0}}};int need[20][20]={{0}};int main(){    scanf("%d%d%d",&N,&M,&K);    for(int i=1;i<=K;i++)        for(int p=1;p<=N;p++)            for(int q=1;q<=M;q++)            {                scanf("%1d",&ch[i][p][q]);                for(int j=1;j<i;j++)                    if(ch[i][p][q]!=ch[j][p][q])                        change[p][q]|=(1<<((i-2)*(i-1)/2-1+j));            }    memset(F,0x3f3f3f3f,sizeof(F));    int Max=(1<<(K*(K-1)/2))-1;    F[0]=0;    int cnt=0;    for(int i=1;i<=N;i++)        for(int j=1;j<=M;j++)        {            for(int p=Max-1;p>=0;p--)            {                if(change[i][j]==0) continue;                if(F[p]+1<F[p|change[i][j]])                {                    F[p|change[i][j]]=F[p]+1;                    memcpy(Matrix[p|change[i][j]],Matrix[p],sizeof(Matrix[p]));                    Matrix[p|change[i][j]][i][j]=1;                }            }        }    printf("%d\n",F[Max]);    for(int i=1;i<=N;i++)    {        for(int j=1;j<=M;j++)            printf("%d",Matrix[Max][i][j]);        puts("");    }    return 0;}
0 0
原创粉丝点击