您的位置:首页 > 其它

poj1185炮兵阵地--状态dp

2014-04-08 18:53 369 查看
炮兵阵地

Time Limit: 2000MSMemory Limit: 65536K
Total Submissions: 17437Accepted: 6669
Description

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

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <vector>
using namespace std;

const int maxn=10;
int dp[102][1<<maxn][1<<maxn];
int map_num[102];
int sum_one[1<<maxn];

vector<int>v[1<<maxn][1<<maxn];
vector<int>::iterator it;

void get_sum_one(int m)
{
int len=(1<<m);
for(int i=0;i<len;i++)
{
int num=i;
int sum=0;
for(int j=1;j<=num;)
{
if(num&j)
sum++;
j<<=1;
}
sum_one[i]=sum;
}
}

bool check_raw(int num)
{
if((num&(num<<1)) || (num&(num<<2)))
return false;

return true;
}

bool check_map(int num,int mp_num)
{
if((num&mp_num)==num)
return true;

return false;
}

bool check_two_lie(int a,int b)
{
if(a&b)
return false;

return true;
}

void init(int m)
{
int len=(1<<m);
for(int i=0;i<len;i++)
{
for(int j=0;j<len;j++)
{
v[i][j].clear();
}
}
for(int i=0;i<len;i++)
{
if(!check_raw(i))
continue;
for(int j=0;j<len;j++)
{
if(!check_raw(j))
continue;
for(int k=0;k<len;k++)
{
if(!check_raw(k))
continue;
if(check_two_lie(i,j) && check_two_lie(i,k) && check_two_lie(j,k))
v[i][j].push_back(k);
}
}
}
}

int main()
{
int n,m;
//freopen("ac.txt","r",stdin);
while(scanf("%d %d",&n,&m)!=EOF)
{

//check1(m);
get_sum_one(m);
init(m);
char str;
int num;
for(int i=0;i<n;i++)
{
int sum=0;
int k=m-1;
for(int j=0;j<m;j++)
{
scanf("\n%c",&str);
num=(str=='P'?1:0);
sum+=num*(1<<k);
k--;
}
map_num[i]=sum;
}
// check2(n);
int len=1<<m;
for(int j=0;j<len;j++)
{
if(check_raw(j) && check_map(j,map_num[0]))
{
dp[0][j][0]=sum_one[j];
}
}
//check3(m);
for(int j=0;j<len;j++)
{
if(!check_raw(j) || !check_map(j,map_num[1]))
continue;
for(int k=0;k<len;k++)
{
if(!check_raw(k) || !check_map(k,map_num[0]))
continue;
if(check_two_lie(j,k))
{
if(dp[1][j][k]<dp[0][k][0]+sum_one[j])
dp[1][j][k]=dp[0][k][0]+sum_one[j];
}
}
}
// check4(m);
for(int i=2;i<n;i++)
{
for(int j=0;j<len;j++)
{
if(!check_map(j,map_num[i-1]))
continue;
for(int k=0;k<len;k++)
{
if(!check_map(k,map_num[i-2]))
continue;
if(v[j][k].size()){
for(int l=0;l<v[j][k].size();l++)
{
int xx=v[j][k][l];
if(check_map(xx,map_num[i]))
if(dp[i][xx][j]<dp[i-1][j][k]+sum_one[xx])
dp[i][xx][j]=dp[i-1][j][k]+sum_one[xx];
}
}
}
}
}
int ans=0;
for(int j=0;j<len;j++)
{
for(int k=0;k<len;k++)
{
if(ans<dp[n-1][j][k])
ans=dp[n-1][j][k];
}
}
printf("%d\n",ans);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: