poj1185炮兵阵地 dp+状态压缩 经典题目
来源:互联网 发布:乐山广电网络客服电话 编辑:程序博客网 时间:2024/06/10 00:30
/*
dp[i][j][k]为第i行的数在第i-1的状态为j第i行的状态为k的最大值
状态转移方程 dp[i][j][k]=max(dp[i][j][k],dp[i-1][s][j]+count(k))
count(k)为状态是k的时候能排的士兵
*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 110
#define maxs 61
char str[maxn][maxn];
int dp[maxn][maxs][maxs];
int useful[maxs];//记下有用的状态
int landstatus[maxn];//记录这个图用二进制表示每一行的状态
int n;int m; //'H'时为1'P'时为0 每一行都有一个状态
//那么判断所选状态能否在该行可行的条件就是‘&’是否为0
int count(int x) //计算状态x所排的士兵
{
int ans=0;
int t=x;
while(t)
{
if(t%2)
ans++;
t/=2;
}
return ans;
}
int init() //找出所有可行的行状态
{
int upper=1<<m;
int k=0;int i;
for(i=0;i<upper;i++)
{
if((i&(i<<1))||(i&(i<<2)))
continue;
useful[k++]=i;
}
return k;
}
int main()
{
int i,j,k,s;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(landstatus,0,sizeof(landstatus));
memset(dp,-1,sizeof(dp));
for(i=0;i<n;i++)
{
scanf("%s",str[i]);
for(j=0;j<m;j++)
if(str[i][j]=='H')
landstatus[i]+=(1<<j);
}
int topper=init();
for(j=0;j<topper;j++)
{
if(useful[j]&landstatus[0])
continue;
dp[0][0][j]=count(useful[j]);
}
for(i=1;i<n;i++)
for(k=0;k<topper;k++)//枚举第i行的情况
{
if(useful[k]&landstatus[i])//判断是否该状态是否在这一行可行
continue;
for(j=0;j<topper;j++)//枚举第i-1的情况
{
if(useful[j]&useful[k])//判断该列是否与前一列冲突
continue;
for(s=0;s<topper;s++)//枚举第i-2的情况
{
if(useful[k]&useful[s])//判断该列是否与前两列冲突
continue;
if(dp[i-1][s][j]==-1)//判断dp[i-1][s][j]是否有可能到达
continue;
dp[i][j][k]=max(dp[i][j][k],dp[i-1][s][j]+count(useful[k]));
}
}
}
int ans=0;
for(j=0;j<topper;j++)
for(k=0;k<topper;k++)
ans=max(ans,dp[n-1][j][k]);
printf("%d\n",ans);
}
}
dp[i][j][k]为第i行的数在第i-1的状态为j第i行的状态为k的最大值
状态转移方程 dp[i][j][k]=max(dp[i][j][k],dp[i-1][s][j]+count(k))
count(k)为状态是k的时候能排的士兵
*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 110
#define maxs 61
char str[maxn][maxn];
int dp[maxn][maxs][maxs];
int useful[maxs];//记下有用的状态
int landstatus[maxn];//记录这个图用二进制表示每一行的状态
int n;int m; //'H'时为1'P'时为0 每一行都有一个状态
//那么判断所选状态能否在该行可行的条件就是‘&’是否为0
int count(int x) //计算状态x所排的士兵
{
int ans=0;
int t=x;
while(t)
{
if(t%2)
ans++;
t/=2;
}
return ans;
}
int init() //找出所有可行的行状态
{
int upper=1<<m;
int k=0;int i;
for(i=0;i<upper;i++)
{
if((i&(i<<1))||(i&(i<<2)))
continue;
useful[k++]=i;
}
return k;
}
int main()
{
int i,j,k,s;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(landstatus,0,sizeof(landstatus));
memset(dp,-1,sizeof(dp));
for(i=0;i<n;i++)
{
scanf("%s",str[i]);
for(j=0;j<m;j++)
if(str[i][j]=='H')
landstatus[i]+=(1<<j);
}
int topper=init();
for(j=0;j<topper;j++)
{
if(useful[j]&landstatus[0])
continue;
dp[0][0][j]=count(useful[j]);
}
for(i=1;i<n;i++)
for(k=0;k<topper;k++)//枚举第i行的情况
{
if(useful[k]&landstatus[i])//判断是否该状态是否在这一行可行
continue;
for(j=0;j<topper;j++)//枚举第i-1的情况
{
if(useful[j]&useful[k])//判断该列是否与前一列冲突
continue;
for(s=0;s<topper;s++)//枚举第i-2的情况
{
if(useful[k]&useful[s])//判断该列是否与前两列冲突
continue;
if(dp[i-1][s][j]==-1)//判断dp[i-1][s][j]是否有可能到达
continue;
dp[i][j][k]=max(dp[i][j][k],dp[i-1][s][j]+count(useful[k]));
}
}
}
int ans=0;
for(j=0;j<topper;j++)
for(k=0;k<topper;k++)
ans=max(ans,dp[n-1][j][k]);
printf("%d\n",ans);
}
}
0 0
- poj1185炮兵阵地 dp+状态压缩 经典题目
- 状态压缩DP poj1185 炮兵阵地
- poj1185 炮兵阵地 状态压缩dp
- poj1185 炮兵阵地 (DP状态压缩)
- poj1185 炮兵阵地 状态压缩dp
- poj1185 炮兵阵地(状态压缩+DP)
- POJ1185 炮兵阵地 (状态压缩DP)
- poj1185 炮兵阵地(状态压缩dp)
- poj1185 炮兵阵地(状态压缩dp)
- poj1185炮兵阵地(状态压缩dp)
- POJ1185 炮兵阵地 (状态压缩DP)
- POJ1185炮兵阵地(状态压缩DP)
- poj1185炮兵阵地(状态压缩DP)
- POJ1185 炮兵阵地 状态压缩DP
- POJ1185:炮兵阵地(状态压缩)
- [状态压缩]poj1185 炮兵阵地
- POJ1185 炮兵阵地 状态DP
- POJ1185——炮兵阵地(状态压缩DP)
- DACL, NULL or not NULL
- Overload和Override的区别
- lua入门学习
- F
- Android消息处理机制
- poj1185炮兵阵地 dp+状态压缩 经典题目
- Android Ksoap 调用webservice 获取二进制数据 byte[] 方法
- 二、动态规划算法
- ffmpeg aac
- Windows NT Session 概念的原理与应用浅析 [1] 遍历并获取信息
- 浅谈tcp_nodelay的作用
- 常用技术(2)
- 程序出错comip.h指向if (m_pInterface != NULL){m_pInterface->Release();}
- vim中的tab和space