zzulioj-1963-Deadline【状压】

本文介绍了一个经典的组合优化问题,通过枚举状态的方法找到最少需要向几个同学借作业才能完成所有科目作业的方案。数据规模较小,适合使用状态压缩进行求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:点击打开链接

1963: Deadline

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值