求大佬帮忙,已写注释方便大佬理解。。

P2704 [NOI2001] 炮兵阵地

北方有小仙儿 @ 2018-09-03 11:26:04

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
int n,m;
long long ans;
long long f[1500][1500][4],sum[1500];
//滚动数组防爆空间 f[k][j][i] 表示当前行状态为j,前一行状态为k,已经处理到i行 
struct edge{
    int s[1500];
    int num;
}a[105];
void prepare(int x,long long t)
{
    for(int i=0;i<(1<<m);i++)
    {
        if((i&t)||(i&(i<<1))||(i&(i<<2)))continue;
        a[x].num++;
        a[x].s[a[x].num]=i;
        int k=0;
        if(sum[i]==0)//sum统计有几个炮兵 
        {
          for(int j=1;j<=m;j++)
            if(i&(1<<j))k++;
          sum[i]=k;
        }
    }
}
void dp()
{ 
    for(int i=1;i<=a[1].num;i++)f[0][i][1]=sum[i];//第一行初始 
    for(int i=1;i<=a[1].num;i++)
      for(int j=1;j<=a[2].num;j++)
        if(a[1].s[i]&a[2].s[j])continue;
        else f[i][j][2]=sum[i]+sum[j];//第二行初始 
    for(int i=3;i<=n;i++)//当前行数 
     for(int k=1;k<=a[i-1].num;k++)// 前一行状态 
      for(int j=1;j<=a[i].num;j++)//当前行状态 
        for(int z=1;z<=a[i-2].num;z++)//上上行状态 
            if((a[i].s[j]&a[i-1].s[k])||(a[i].s[j]&a[i-2].s[z])||(a[i-1].s[k]&a[i-2].s[z]))continue;
            else {
               f[k][j][i%3]=max(f[k][j][i%3],f[z][k][(i-1)%3]+sum[j]); 
               ans=max(f[k][j][i%3],ans);
            } 
    cout<<ans;
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        long long t=0;
        char x[15];
        cin>>x;
        for(int j=0;j<m;j++)
        { 
            if(x[j]=='H')t=(t<<1)+1;
            if(x[j]=='P')t=(t<<1)+0;
        }
        prepare(i,t);
    }
    dp();
    return 0;
}

|