Acdream 1132 Chess(状压dp)

本文详细探讨了中国象棋中将的最优布局策略问题,包括棋盘大小、放置条件以及如何最小化所需的将的数量,同时通过实例分析了不同布局情况下的解法。

Chess

Time Limit: 2000/1000MS (Java/Others)  Memory Limit: 128000/64000KB (Java/Others)
Problem Description

Xiang-qi is a kind of traditional Chinese chess. There is a special role in the game called “Jiang” (or called “Shuai”). When you want to operate this kind of role, it can only dominating the four neighbor cell and can of course attack the role there (In fact there is a special condition can allow the role attack farther distance but we ignore this condition).

Now we have an N*N chessboard, we want to place some “Jiang” on it. Of course we have several restraints on placing chess pieces:

1. The placing chess role cannot dominate each other.
2. On the chessboard all cells without placing chess should be dominated.
3. There are some cells called “Hole” which cannot be placed by chess piece. Attention that the hole should also be dominated.

For a given chessboard, we want to know the least number of chess pieces to place which can satisfy the restraints above.

Input

There are multiple test cases.

In each test case, the first line contains two integers N and K indicating the size of the chessboard and the number of the holes on the chessboard. (1 <= N <= 9, 0 <= K <= N*N)

In the next K line each line contains two integers x and y indicating the cell (x, y) is a hole cell. (1 <= x, y <= N)

You can get more details from the sample and hint.

Output

For each test case, you should output an integer indicating the answer of the test case. If there is no way to place the chess pieces, please output -1.

Sample Input
3 2
1 1
3 3
Sample Output
3
Hint

In the sample we can have several ways to placing the chess pieces:

Place on (1, 3), (2, 1) and (3, 2);
Place on (3, 1), (1, 2) and (2, 3);

Although place on (1, 2), (2, 2) and (3, 2) can dominate all cell but it is not satisfy the first restraint. And place on (1, 1), (1, 3) and (3, 2) is also illegal because the cell (1, 1) is a hole.


题目链接:http://acdream.info/problem?pid=1132



//dp[i][cur][up] 代表 i行 type[cur]状态,i-1行是type[up]时放的棋子数目

//思路:先预处理哪一些状态没有相邻的1, 状态中1代表放了  将  ,
//因为放第i行时当前状态不能喝hole冲突,且不能喝i-1行状态冲突,且必须使得i-1行中的格子都要被控制,
//而i-1行被控制的状态与i-2也有关,所以也要记录i-2行的状态,所以用3维dp

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>


#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MID(x,y) ((x+y)>>1)

#define eps 1e-8
//typedef __int64 ll;

#define fre(i,a,b)  for(i = a; i < b; i++)
#define frer(i,a,b) for(i = a; i > =b;i--)
#define mem(t, v)   memset ((t) , v, sizeof(t))
#define ssf(n)      scanf("%s", n)
#define sf(n)       scanf("%d", &n)
#define sff(a,b)    scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf          printf
#define bug         pf("Hi\n")

using namespace std;

#define INF 0x3f3f3f3f
#define N 520

int dp[10][N][N];
int type[N],k;
int n,m,h[10],num[N];

int lowbit(int x)     //计算x状态1的数目
{
	int t=0;
	while(x)
	{
		t++;
		x&=(x-1);
	}
   return t;
}

bool ok(int x)
{
	if(x&(x<<1)) return false;
	return true;
}

void inint()       //预处理每一行没有相邻的11状态
{
	int i,j;
	int len=1<<n;
	k=0;
	fre(i,0,len)
	 if(ok(i))
		type[k++]=i;

	fre(i,0,k)
	  num[i]=lowbit(type[i]);    //求出这一种状态的1的数目
}

void solve()
{
     int i,j,cur,up,uup;
     fre(i,2,n)
       fre(cur,0,k)      //当前状态
       {
       	   if(type[cur]&h[i]) continue;

       	   fre(up,0,k)         //上一行状态
       	   {
       	   	  if(type[up]&h[i-1]) continue;
       	   	  if(type[up]&type[cur]) continue;

       	   	  fre(uup,0,k)       //上上一行状态
       	   	  {
       	   	      if(type[uup]&h[i-2]) continue;
       	   	      if(type[uup]&type[up]) continue;
                  if(!dp[i-1][up][uup]) continue;
       	   	      int t=type[up]|(type[up]<<1)|(type[up]>>1);
       	   	      t|=type[uup];
       	   	      t|=type[cur];
       	   	      t&=(1<<n)-1;    //这一步很重要,bug半天
       	   	      if(t!=(1<<n)-1) continue;
       	   	      dp[i][cur][up]=min(dp[i][cur][up],dp[i-1][up][uup]+num[cur]);
       	   	  }
       	   }
       }
	int ans=INF;

	fre(i,0,k)
	 fre(up,0,k)
	 {
	 	if(dp[n][i][up]==INF)  continue;
	 	if(h[n]&type[i]) continue;
	 	if(h[n-1]&type[up]) continue;
	 	if(type[i]&type[k]) continue;
	 	int t=type[i]|(type[i]<<1)|(type[i]>>1);
	 	t|=type[up];
	 	t&=(1<<n)-1;
	 	if(t!=(1<<n)-1) continue;
	 	if(!dp[n][i][up]) continue;
	 	ans=min(ans,dp[n][i][up]);
	 }
     if(ans==INF) ans=-1;
     printf("%d\n",ans);
}

int main()
{
    int i,j;
    while(~sff(n,m))
	{
       inint();
       mem(h,0);
       int x,y;
       while(m--)
	   {
	   	  sff(x,y);
	   	  h[x]|=1<<(y-1);
	   }

       mem(dp,0);

       fre(i,0,k)
         {
         	if(type[i]&h[1]) continue;
         	dp[1][i][0]=num[i];
         }
	solve();
	}
	return 0;
}


【轴承故障诊断】加权多尺度字典学习模型(WMSDL)及其在轴承故障诊断上的应用(Matlab代码实现)内容概要:本文介绍了加权多尺度字典学习模型(WMSDL)在轴承故障诊断中的应用,并提供了基于Matlab的代码实现。该模型结合多尺度分析与字典学习技术,能够有效提取轴承振动信号中的故障特征,提升故障识别精度。文档重点阐述了WMSDL模型的理论基础、算法流程及其在实际故障诊断中的实施步骤,展示了其相较于传统方法在特征表达能力和诊断准确性方面的优势。同时,文中还提及该资源属于一个涵盖多个科研方向的技术合集,包括智能优化算法、机器学习、信号处理、电力系统等多个领域的Matlab仿真案例。; 适合人群:具备一定信号处理和机器学习基础,从事机械故障诊断、工业自动化、智能制造等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①学习并掌握加权多尺度字典学习模型的基本原理与实现方法;②将其应用于旋转机械的轴承故障特征提取与智能诊断;③结合实际工程数据复现算法,提升故障诊断系统的准确性和鲁棒性。; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,重点关注字典学习的训练过程与多尺度分解的实现细节,同时可参考文中提到的其他相关技术(如VMD、CNN、BILSTM等)进行对比实验与算法优化。
【硕士论文复现】可再生能源发电与电动汽车的协同调度策略研究(Matlab代码实现)内容概要:本文档围绕“可再生能源发电与电动汽车的协同调度策略研究”展开,旨在通过Matlab代码复现硕士论文中的核心模型与算法,探讨可再生能源(如风电、光伏)与大规模电动汽车接入电网后的协同优化调度方法。研究重点包括考虑需求侧响应的多时间尺度调度、电动汽车集群有序充电优化、源荷不确定性建模及鲁棒优化方法的应用。文中提供了完整的Matlab实现代码与仿真模型,涵盖从场景生成、数学建模到求解算法(如NSGA-III、粒子群优化、ADMM等)的全过程,帮助读者深入理解微电网与智能电网中的能量管理机制。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的研究生、科研人员及从事新能源、智能电网、电动汽车等领域技术研发的工程人员。; 使用场景及目标:①用于复现和验证硕士论文中的协同调度模型;②支撑科研工作中关于可再生能源消纳、电动汽车V2G调度、需求响应机制等课题的算法开发与仿真验证;③作为教学案例辅助讲授能源互联网中的优化调度理论与实践。; 阅读建议:建议结合文档提供的网盘资源下载完整代码,按照目录顺序逐步学习各模块实现,重点关注模型构建逻辑与优化算法的Matlab实现细节,并通过修改参数进行仿真实验以加深理解。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值