洛谷P2622


声明:

本篇文章不讲基础,对萌新不太友好,(我就是萌新),要学状压$dp$的请另寻,这篇文章只是便于本人查看。。。。


首先看到$n<=10$,就可以考虑状压了,要求最小值,所以初始化大一点,我们设$f[i]$表示当前状态为$i$的最少按按钮数

所以$f[(1<<n)-1]$初始化为$0$,因为初始状态不需要按按钮。

开始转移状态,我们第一层循环从全开的状态到全关的状态,第二层枚举这次用哪个开关,第三层枚举这次开关的影响。最终状态$f[0]$就是答案,代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 11
#define M 101
using namespace std;
int n,m;
int val[M][N],f[1<<N];
int main()
{
	memset(f,0x3f,sizeof(f));
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;++i)
		for(int j=1;j<=n;++j)
			scanf("%d",&val[i][j]);
	f[(1<<n)-1]=0;
	for(int i=(1<<n)-1;i>=0;--i)
		for(int j=1;j<=m;++j)
		{
			int now=i;
			for(int k=1;k<=n;++k)
			{
				if(!val[j][k])
					continue;
				if(val[j][k]==1&&(i&(1<<(k-1))))
					now^=1<<(k-1);
				if(val[j][k]==-1&&!(i&(1<<(k-1))))
					now^=1<<(k-1);
			}
			f[now]=min(f[now],f[i]+1);
		}
	if(f[0]==0x3f3f3f3f)
		printf("-1");
	else
		printf("%d",f[0]);
	return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/yexinqwq/p/10176874.html
今日推荐