zoukankan      html  css  js  c++  java
  • [NOI2001]炮兵阵地

    题目描述

    司令部的将军们打算在NM的网格地图上部署他们的炮兵部队。一个NM的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图。在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队);一支炮兵部队在地图上的攻击范围如图中黑色区域所示:

    如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格。图上其它白色网格均攻击不到。从图上可见炮兵的攻击范围不受地形的影响。 现在,将军们规划如何部署炮兵部队,在防止误伤的前提下(保证任何两支炮兵部队之间不能互相攻击,即任何一支炮兵部队都不在其他支炮兵部队的攻击范围内),在整个地图区域内最多能够摆放多少我军的炮兵部队。

    输入输出格式

    输入格式:

    第一行包含两个由空格分割开的正整数,分别表示N和M;

    接下来的N行,每一行含有连续的M个字符(‘P’或者‘H’),中间没有空格。按顺序表示地图中每一行的数据。N≤100;M≤10。

    输出格式:

    仅一行,包含一个整数K,表示最多能摆放的炮兵部队的数量。

    输入输出样例

    输入样例#1:

    5 4
    PHPP
    PPHH
    PPPP
    PHPP
    PHHP

    输出样例#1:
    6


    状压dp

    由于(Mleq 10)而且相邻3个位置内不能放两个以上炮兵,所以其实真正每行能放的状态是很少的。
    其实每一次对新的一行转移时对他有影响的只有向上两行,加到状态里就行了。
    那么先找出每一种可行的状态,两两看是否匹配。
    暴力转移即可


    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define LL long long
    #define max(a,b) ((a)>(b)? (a):(b))
    #define min(a,b) ((a)<(b)? (a):(b))
    
    using namespace std;
    
    int b[101],i,m,n,j,k,a[101][101][101],d[100],v[100],bl[101][101],l,ans,bb[101][101][101];
    char c;
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(i=1;i<=n;i++)
    		for(j=1;j<=m;j++) 
    		{
    			b[i]<<=1;
    			scanf("%c",&c);
    			while(c!='P' && c!='H')	scanf("%c",&c);
    			if(c=='H') b[i]+=1;
    		}
    		
    	for(i=0;i<=(1<<m)-1;i++)
    	{
    		if((i&(i<<1))||(i&(i<<2))) continue;
    		int t=i; k=0;
    		while(t) t-=t & -t, k+=1;
    		v[++v[0]]=k;
    		d[++d[0]]=i;
    	}
    	
    	for(i=1;i<=d[0];i++) 
    		if(!(b[1]&d[i]))  
    		{
    			bb[1][1][i]=1;
    			a[1][1][i]=v[i];
    		}
    	for(i=1;i<=d[0];i++)
    		for(j=1;j<=d[0];j++) 
    			if(!(d[i]&d[j])) bl[i][j]=1;
    			
    	for(i=2;i<=n;i++)
    		for(j=1;j<=d[0];j++)
    			for(l=1;l<=d[0];l++)
    				if(bb[i-1][j][l])
    				for(k=1;k<=d[0];k++)
    				if(bl[k][l] && bl[k][j] &&(!(d[k]&b[i])))
    				{
    					bb[i][l][k]=1;
    					a[i][l][k]=max(a[i][l][k],a[i-1][j][l]+v[k]);
    					if(i==n) ans=max(ans,a[i][l][k]);
    				}
    				
    	printf("%d",ans);
    }
    
  • 相关阅读:
    linux下nginx+php+mysql环境搭建
    Linux下配置安装PHP环境
    什么是Apache APR
    全端之Jquery--操作属性
    全端之jQuery基本语法
    全端之Javascript(操作DOM对象二)
    全端之Javascript(DOM对象三)
    全端之Javascript(DOM对象一)
    全端之Javascript对象
    全端开发——css(操作属性补充)
  • 原文地址:https://www.cnblogs.com/ZUTTER/p/9805601.html
Copyright © 2011-2022 走看看