POJ 1185 炮兵阵地 状压DP
http://poj.org/problem?id=1185
中文题目,开始觉得跟上个题目,种玉米那个一样的,只是这个是第三行受前两行的影响,,,后来发现不是。种玉米是最后有多少组合,这个是最多放多少部队,稍稍一变就行了
总体来说,这个题不是很难,还可以,就是我写的很纠结 MLE,TLE 用滚动数组解决了MLE,二进制预处理解决TLE 最后还是跑了1400+MS
代码:
//开始还MLE,dp[103][MAX+5][MAX+5]确实是超,后来用了滚动数组改成了TLE,最后预处理还跑了1400+MS
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#define MAX (1<<10)
using namespace std;
int dp[2][MAX+5][MAX+5];
vector<int>num[103];
int i,j,k;
int r,c;
int max(int a,int b)
{
return a>b?a:b;
}
void Get_state(int row,int temp)
{
num[i].clear();
for(int x=0;x<(1<<c);x++)
{
if(x&(x<<1) || x&(x<<2) || x&(x>>1) || x&(x>>2)) continue;
if(temp&x) continue;
num[i].push_back(x);
}
}
void Judge()
{
int t1,t2,t3;
int cnt;
for(t1=0;t1<num[i-2].size();t1++)
for(t2=0;t2<num[i-1].size();t2++)
for(t3=0;t3<num[i].size();t3++)
{
if((num[i][t3]&num[i-2][t1])||(num[i][t3]&num[i-1][t2])) continue;
cnt=0;
int h=num[i][t3];
while(h)
{
if(h%2) cnt++;
h/=2;
}
dp[i%2][t2][t3]=max(dp[i%2][t2][t3],dp[(i-1)%2][t1][t2]+cnt);
}
}
int main()
{
char s[20];
int temp;
while(~scanf("%d%d",&r,&c))
{
num[0].clear();
num[0].push_back(0);
num[1].clear();
num[1].push_back(0);
for(i=2;i<=r+1;i++)
{
scanf("%s",s);
temp=0;
for(j=0;j<c;j++)
{
if(s[j]=='H') temp+=(1<<j);
}
Get_state(i,temp);
}
memset(dp,0,sizeof(dp));
for(i=2;i<=r+1;i++)
{
for(int h1=0;h1<num[i-1].size();h1++)
for(int h2=0;h2<num[i].size();h2++)
dp[i%2][h1][h2]=0;
Judge();
}
int ans=0;
for(i=0;i<num[r].size();i++)
for(j=0;j<num[r+1].size();j++)
{
ans=max(ans,dp[(r+1)%2][i][j]);
}
printf("%d\n",ans);
}
return 0;
}

浙公网安备 33010602011771号