题目链接:点击打开链接
1963: Deadline
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 16 Solved: 10
Submit Status Web Board
Description
刷了一天题的zy已经筋疲力尽,正在他准备上床时,才意识到自己所有科目的作业都没写,但这个时候再认真写
就已经晚了,于是他只好找同学抄,但其实班里也只有那么寥寥几个人写了作业,这就让zy非常头疼,因为平时分还是
非常重要的。
现已知有m门科目要交作业,班里只有n个人写了作业,问zy至少要找多少人借作业才能把所有作业全部搞定
PS:zy找同学借作业时会将那个同学的所有作业全部借来
Input
单实例测试,
第一行输入两个正整数n,m(n,m<=7)
接下来是一个n*m的01矩阵,第i行第j列为1表示第i个人做了第j门作业,为0表示没做,数据保证每个作业至少有一个人做了
Output
输出一个整数表示zy最少要找多少人
Sample Input
5 71 0 0 1 1 1 10 1 0 0 1 1 00 0 1 1 0 0 10 1 1 0 0 0 11 0 1 0 1 1 1
Sample Output
2
HINT
对于样例,zy只要找第1个同学和第4个同学即可!
思路:
题目数据小,可以暴力枚举每一种情况!
首先分析每个人都有借和不借两种情况,这样 m 个人就是 2 ^ m 种情况,因为 m<=7。用一个数的二进制表示状态就好了,比如5的二进制是0000101,对应的状态是 “ 只向第 1 个人和第 3 个人借 ",枚举每一种状态判断它是否能借到所有的作业,更新最优解。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m;
bool a[10][10];
bool vis[10];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
}
}
int ans=n;
for(int i=1;i<(1<<7);i++)
{
int cnt=0;
memset(vis,0,sizeof(vis));
for(int j=0;j<7;j++)
{
if(i&(1<<j))
{
cnt++;
for(int k=1;k<=m;k++)
{
if(!vis[k])
vis[k]=a[j+1][k];
}
}
}
bool temp=1;
for(int k=1;k<=m;k++)
{
if(!vis[k])
{
temp=0;
break;
}
}
if(temp)
ans=min(ans,cnt);
}
printf("%d\n",ans);
return 0;
}