uva11205 生成子集

来源:互联网 发布:软件建设方案 编辑:程序博客网 时间:2024/05/19 23:28

题目大意:

数码管由七根LED灯管构成,其中若灯管有坏掉情况下有时仍能分辨出是什么数字。题目想问最少有几根灯管就可以分辨出所有的输入符号。

抽象一下实际就是给出一个0,1矩阵,问至少需要几列可以区别所有的行。

这道题开始不会做,看了生成子集算法才会的,幸亏输入数据不大,否则肯定超时了啊,AC过的时间都2000ms了。。

我是用位向量法生成子集的,即用一个数组B【i】=1来表示i是否位于子集A中,依次选择是否将i加入子集A中,最后输出所得的子集结果。因为这个题N要求不大于100,所以可以两两比较,这样复杂度O(n2)也不是很大,但我计算了每一行在某个子集下的“值”(比如说P=10的某个子集是0,1,2,3,4,我计算了每一行的0,1,2,3,4列的数乘以该列的权值,得到了一个唯一值),用了一个flag【】数组存储是否已经访问过该“值”,能分辨出每个行的充分必要条件就是每一行的“值”均不相同。

#include<iostream>#include<cstring>#include<cmath>using namespace std;int np,P,N,Minp;int grid[105][16];bool flag[65536];void subset(int n,int B[],int cur){if (cur==n){memset(flag,0,sizeof(flag));int count=0;for (int i=0;i<N;i++){int dex=0;for (int k=0;k<cur;k++){if (B[k]){if (i==0) count++;dex=dex+grid[i][k]*(int)pow(2,double(k));}}if (pow(2,(double)count)<P) return;if (flag[dex]==0)flag[dex]=1;else return;}if (count<Minp) Minp=count;return;}B[cur]=1;subset(n,B,cur+1);B[cur]=0;subset(n,B,cur+1);}int main(){cin>>np;while(np--){cin>>P>>N;for (int i=0;i<N;i++){for (int j=0;j<P;j++){cin>>grid[i][j];}}Minp=P;int array[16];subset(P,array,0);cout<<Minp<<endl;}return 0;}


原创粉丝点击