一道深度优先搜索题,其实dp应该也可以 只是目前对dp还不是很熟练
上代码看注释吧
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<stack>
#include<queue>
#include<cmath>
#include<stack>
#include<list>
#include<map>
#include<set>
typedef long long ll;
using namespace std;
int book[20]; //记录第i层 开着灯的房间的个数
char a[20][110]; //输入的地图
int b[20][3]; // 记录第i层最左边和最右边的开灯房间的位置 b[i][0]代表最左 b[i][1]代表最右边
int cnt=0;//记录开灯房间的总个数
int m,n;
int maxn=0xffffff; // 要输出的答案 不断更新maxn 使其最小
void dfs(int t,int p,int ge,int d) //t代表层数,p是pace,代表时间 ge代表当前已经关掉了ge个灯,d代表方向,d==0代表从左楼梯上,==1代表从右楼梯上
{
if(ge==cnt)
{
maxn=min(maxn,p);
return ;
}
if(d==0) //从左楼梯上来的,此时人位于最左边
{
if(b[t][1]!=-1&&b[t][0]!=-1) //如果这一层存在开着的灯
{
if(ge+book[t]==cnt) //关完这一层的灯就全部关掉了
{
maxn=min(maxn,p+b[t][1]);
return ;
}
else
{
dfs(t-1,p+2*b[t][1]+1,ge+book[t],0); //仍然从左楼梯上楼,要走来回 所以是2倍 上楼花一分钟
dfs(t-1,p+m+1+1,ge+book[t],1); //换到右楼梯上楼 相当于直接走到右边 上楼花一分钟
}
}
else //如果这一层不存在开着的灯
{
dfs(t-1,p+1,ge,0); //直接进入下一层
dfs(t-1,p+m+1+1,ge,1); //走到右楼梯 再进入下一层
}
}
else if(d==1) //从右楼梯上来的,此时人位于最右边
{
if(b[t][1]!=-1&&b[t][0]!=-1)
{
if(ge+book[t]==cnt)//关完这一层的灯就全部关掉了
{
maxn=min(maxn,p+m+1-b[t][0]);
return ;
}
else
{
dfs(t-1,p+2*(m+1-b[t][0])+1,ge+book[t],1);
dfs(t-1,p+m+1+1,ge+book[t],0);
}
}
else
{
dfs(t-1,p+1,ge,1);
dfs(t-1,p+m+1+1,ge,0);
}
}
return;
}
int main()
{
int i,j,k;
scanf("%d%d",&n,&m);
maxn=0xffffff;
cnt=0;
memset(b,-1,sizeof b); //初始化为-1
memset(book,0,sizeof book);
getchar();
for(i=1;i<=n;i++)
{
int flag=0;
for(j=0;j<=m+1;j++)
{
scanf("%c",&a[i][j]);
if(a[i][j]=='1')
{
cnt++;
book[i]++;
if(flag==0)
{
flag=1;
b[i][0]=j;
}
}
}
getchar();
for(j=m+1;j>=0;j--)
{
if(a[i][j]=='1')
{
b[i][1]=j;
break;
}
}
}
dfs(n,0,0,0);
printf("%d\n",maxn);
return 0;
}