版权声明:转载请附带原文链接,请勿随意删除原文内容,允许少量格式和/或内容修改,谢谢! https://blog.csdn.net/weixin_37661548/article/details/87390933
参考代码
#include <bits/stdc++.h>
using namespace std;
int n,m;
int effect[105][15],dp[1 << 12];
void init()
{
scanf("%d%d",&n,&m);
for (int i = 1; i <= m; ++i)
for (int j = 1; j <= n; ++j)
scanf("%d",&effect[i][j]);
memset(dp,0x3f,sizeof(dp));
dp[(1 << n) - 1] = 0;
}
void work()
{
for (int s = (1 << n) - 1; s; --s)
{
for (int Switch = 1; Switch <= m; ++Switch)
{
int newState = s;
for (int l = 1; l <= n; ++l)
{
switch (effect[Switch][l])
{
case 1 :
{
newState = newState & ~ (1 << (l - 1));
break;
}
case -1 :
{
newState = newState | (1 << (l - 1));
break;
}
default : break;
}
}
dp[newState] = min(dp[newState],dp[s] + 1);
}
}
printf("%d",dp[0] == 0x3f3f3f3f ? -1 : dp[0]);
}
int main()
{
init();
work();
return 0;
}
分析
- 设 为灯状态为 时所需最少操作次数。
- 显然, (全关)就是答案, ,问最少,将 初始化为极大值。
- 枚举所有的状态,再枚举所有的开关 ,则 ,其中, 是状态 经过按动开关 后的状态,最坏需要开关数+1。
- 如何根据状态 推得状态 ?根据题意, 代表开关i控制灯的情况,对于状态 和开关 ,枚举所有的灯 ,取末 位,得到该灯的状态,进行操作即可。
- 注意:假设有n件“物品”,“全选”代表的状态为 ,不要忘了 。