游客 Signup | Login
中文 | En

2986 - 棋盘覆盖

给出一张nn(n<=100)的国际象棋棋盘,其中被删除了一些点,问可以使用多少12的多米诺骨牌进行掩盖。

Input

第一行为n,m(表示有m个删除的格子)
第二行到m+1行为x,y,分别表示删除格子所在的位置
x为第x行
y为第y列

Output

一个数,即最大覆盖格数

Examples

Input

8 0

Output

32

Solution C++

#include<iostream>
using namespace std;
int n,m,ans(0),a[5005][10],match[5005],x=0,y=0,num[10005];
bool used[5005],can[10005];
void init()
{
	cin>>n>>m;
	fill(can,can+10005,1);
	for (int i=1,b,c;i<=m;i++)
    {
    cin>>b>>c;
    can[(b-1)*n+c]=false;
    }
    for (int i=1;i<=n;i++)
    for (int j=1;j<=n;j++)
    if ((i+j)%2==0&&can[(i-1)*n+j]) num[(i-1)*n+j]=(++y);
    for (int i=1;i<=n;i++)
    for (int j=1;j<=n;j++)
    {
    	if ((i+j)%2==1&&can[(i-1)*n+j])
    	{
		    a[++x][0]=0;
		    if (can[(i-1)*n+j-1]&&j-1>0)
		    a[x][++a[x][0]]=num[(i-1)*n+j-1];
		    if (can[(i-1)*n+j+1]&&j+1<=n)
		    a[x][++a[x][0]]=num[(i-1)*n+j+1];
		    if (can[(i-2)*n+j]&&i-2>=0)
            a[x][++a[x][0]]=num[(i-2)*n+j];
            if (can[(i)*n+j]&&i<n)
            a[x][++a[x][0]]=num[(i)*n+j];
        }
    
}
}
bool cross(int k)
{
	if (!k) return false;
	for (int i=1;i<=a[k][0];i++)
	{
		int j=a[k][i];
		if (!used[j])
		{
			used[j]=true;
			if (!match[j]||cross(match[j]))
            {
             match[j]=k;
             return true;
            }
		}
	}
	return false;
}
void solve()
{
	for (int i=1;i<=x;i++)
	{
		if (cross(i))
		ans++;
		fill(used,used+5005,0);
	}
}
int main()
{
	init();
	solve();
	cout<<ans<<endl;
	return 0;
}
Time Limit 1 second
Memory Limit 128 MB
Discuss Stats
上一题 下一题