• 洛谷P2622关灯问题-状态压缩广度优先搜索


    具体解法是:对队首的某一状态,枚举每一个开关灯操作,记录到达这一新状态的步数(也就是老状态 + 1),若是最终答案,输出,若不是,压入队列。采用结构体记录每个节点,包含当前状态和步数。

    #include<bits/stdc++.h>
    using namespace std;
    typedef struct{
    	int status,cnt;
    }NODE;
    int vis[100020]={0};
    int arr[200][200]={0};
    int n,m;int num=0,min_step=9999;
    queue<NODE> steps;
    
    void bfs(int level)
    { 
    	if(steps.empty())return;
    	NODE pre_node=steps.front();
    	steps.pop();
    	if(pre_node.status==0)
    	{
    		cout<<pre_node.cnt;
    		min_step=min(min_step,pre_node.cnt);
    		return;
    	}
    	for(int i=1;i<=m;i++)
    	{//枚举所有状态
    		NODE new_node=pre_node;
    		int new_status=new_node.status;
    		for(int j=1;j<=n;j++)
    		{
    			if(arr[i][j]==1)
    			{
    				if(new_status&(1<<(n-j)))//说明是1
    					new_status=new_status^(1<<(n-j));
    			}
    			if(arr[i][j]==-1)
    			{
    				new_status=new_status|(1<<(n-j));
    			}
    		}
    
    		if(!vis[new_status])
    		{
    			new_node.status=new_status;
    			new_node.cnt=level;
    			steps.push(new_node);
    			vis[new_status]=1;
    		}
    	}
    	bfs(steps.front().cnt+1);
    }
    int main()
    {
    	cin>>n>>m;
    	for(int i=0;i<n;i++)
    		{
    			num=(num<<1)+1;
    		}
    	NODE node={num,0};
    	steps.push(node);
    	for(int i=1;i<=m;i++)
    	{
    		for(int j=1;j<=n;j++)
    			cin>>arr[i][j];
    	}
    	vis[num]=1;
    	bfs(1);
    	if(min_step==9999) cout<<-1<<endl;
    	return 0;
    }
    

    较为简便的递推dp代码:

    #include<bits/stdc++.h>
    using namespace std;
    vector<int>dp(1025,-1);int arr[200][200];
    int n,m;
    int main()
    {
    	queue<int>q;
    	cin>>n>>m;
    	for(int i=1;i<=m;i++)
    	{
    		for(int j=1;j<=n;j++)
    			cin>>arr[i][j];
    	}
    	q.push((1<<n)-1);dp[(1<<n)-1]=0;
    	while(!q.empty())
    	{
    		
    		int c_state=q.front();
    		q.pop();
    		for(int i=1;i<=m;i++)
    		{
    			int n_state=c_state;
    			for(int j=1;j<=n;j++)
    			{
    				if(arr[i][j]==1)
    					if(n_state&(1<<(n-j)))
    					n_state=n_state^(1<<(n-j));
    				if(arr[i][j]==-1)
    					n_state=n_state|(1<<(n-j));
    			}
    			//cout<<dp[n_state]<<endl;
    			if(dp[n_state]==-1)
    			{	
    				dp[n_state]=dp[c_state]+1;
    				q.push(n_state);
    			}
    		}
    	}
    	cout<<dp[0]<<endl;
    	return 0;
    }
    
    作者:xmsi
    出处:http://www.cnblogs.com/tldr/
    本文版权归作者和博客园共有,欢迎转载,但转载时请保留此段声明。
  • 相关阅读:
    同库 不同表更新
    js 随机时间
    转 vagrant package[打包命令]详解
    mysql 批量更新与批量更新多条记录的不同值实现方法 (转)
    vagrant up时提示 Authentication failure. Retrying
    vagrant 错误记录
    签名保存
    linux下svn命令大全
    linux 搭建SVN服务器,为多个项目分别建立版本库并单独配置权限
    log file sync
  • 原文地址:https://www.cnblogs.com/tldr/p/10890378.html
Copyright © 2020-2023  润新知