• 【CF845F】Guards In The Storehouse 插头DP


    【CF845F】Guards In The Storehouse

    题意:一个n*m的房间,每个格子要么是障碍要么是空地。对于每个空地你可以选择放或者不放守卫。一个守卫能保护到的位置是:他右面的一行空地+下面的一列空地,但是不能穿过障碍(可以穿过另一个守卫)。现在要求至多有1个空地没有被保护,求放置守卫的方案数。

    $n imes mle 250$

    题解:n和m中较小者不超过15,所以插头DP不解释~

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    const int P=1000000007;
    int f[2][(1<<16)+1][2];
    int n,m,msk,ans;
    char str[255][255];
    inline void upd(int &x,int y) {x+=y;	if(x>=P)	x-=P;}
    int main()
    {
    	scanf("%d%d",&n,&m);
    	int i,j,d=0,S,T,p,q,x,y,v0,v1;
    	for(i=0;i<n;i++)	scanf("%s",str[i]);
    	if(n<m)
    	{
    		for(i=0;i<n;i++)	for(j=i;j<m;j++)	swap(str[i][j],str[j][i]);
    		swap(n,m);
    	}
    	msk=(1<<(m+1))-1,f[0][0][0]=1;
    	for(i=0;i<n;i++)
    	{
    		for(j=0;j<m;j++)
    		{
    			d^=1,memset(f[d],0,sizeof(f[d]));
    			for(S=0;S<=msk;S++)
    			{
    				x=j,y=j+1,p=(S>>x)&1,q=(S>>y)&1,T=S^(p<<x)^(q<<y),v0=f[d^1][S][0],v1=f[d^1][S][1];
    				if(!v0&&!v1)	continue;
    				if(str[i][j]=='x')
    				{
    					upd(f[d][T][0],v0),upd(f[d][T][1],v1);
    					continue;
    				}
    				upd(f[d][T|(1<<x)|(1<<y)][0],v0),upd(f[d][T|(1<<x)|(1<<y)][1],v1);
    				if(p||q)	upd(f[d][T|(q<<x)|(p<<y)][0],v0),upd(f[d][T|(q<<x)|(p<<y)][1],v1);
    				else	upd(f[d][T][1],v0);
    			}
    		}
    		d^=1,memset(f[d],0,sizeof(f[d]));
    		for(S=0;S<=msk;S++)	upd(f[d][(S<<1)&msk][0],f[d^1][S][0]),upd(f[d][(S<<1)&msk][1],f[d^1][S][1]);
    	}
    	for(S=0;S<=msk;S++)	upd(ans,f[d][S][0]),upd(ans,f[d][S][1]);
    	printf("%d",ans);
    	return 0;
    }//1 4  ....
  • 相关阅读:
    Linux 配置yum源(互联网)
    Linux SSH远程链接 短时间内断开
    loadrunner12安装教程
    Jmeter关联处理
    JMeter做http接口压力测试
    面试试题库
    Selenium基础之--01(将浏览器最大化,设置浏览器固定宽、高,操控浏览器前进、后退)
    索引(快速查询)
    视图是什么玩意
    mysql面试常见题目3
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/8283085.html
Copyright © 2020-2023  润新知