Processing math: 33%

【NOI2001】炮兵阵地

题面

https://www.luogu.org/problem/P2704

题解

状态压缩dp的经典题了吧。

因为直接压压不动,所以我写的是hash+记忆化。

复制代码
#include<cstdio>
#include<iostream>
#define mod 5000007
#define ri register int
using namespace std;
struct Hash{
  long long val;
  int f;
} hash[5000010];
char mp[105][15];
int n,m,ans,val[1500],ss[105];

int value(int x){
  int ans=0;
  for (ri i=1;i<=m;i++) {
    if (x&(1<<(i-1))) ans++;
  }
  return ans;
}

bool can(int x,int cur) {
  if (x&(x<<1)) return 0;
  if (x&(x<<2)) return 0;
  if (x&(x>>1)) return 0;
  if (x&(x>>2)) return 0;
  if (x&ss[cur]) return 0;
  return 1;
}

int dfs(ri cur,ri s1,ri s2) {
  if (cur==n+1) return 0;

  long long yuan=(((s2<<m)+s1)<<7)+cur;
  ri hx=yuan%mod;

  if (hash[hx].val) {
    while (hash[hx].val && hash[hx].val!=yuan) {
      hx++;
      if (hx==mod) hx=0;
    }
    if (hash[hx].val==yuan) return hash[hx].f;
  }
  hash[hx].val=yuan;

  int as=0;
  for (ri i=0;i<=(1<<m)-1;i++) {
    if ((i&s1)==0 && (i&s2)==0  && can(i,cur)) as=max(as,val[i]+dfs(cur+1,i,s1));
  }
  hash[hx].f=as;
  return as;
}

int main() {
  string st;
  scanf("%d %d",&n,&m); getline(cin,st);
  for (ri i=0;i<(1<<m);i++) val[i]=value(i);
  for (ri i=1;i<=n;i++) {
    ss[i]=0;
    for (ri j=1;j<=m;j++) {
      mp[i][j]=getchar();
      if (mp[i][j]=='H') ss[i]|=(1<<(j-1)); 
    }
    getline(cin,st);
  }
  ans=dfs(1,0,0);
  cout<<ans<<endl;
}
复制代码

 

posted @   HellPix  阅读(136)  评论(0编辑  收藏  举报
编辑推荐:
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
阅读排行:
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 《HelloGitHub》第 106 期
· 数据库服务器 SQL Server 版本升级公告
· C#/.NET/.NET Core技术前沿周刊 | 第 23 期(2025年1.20-1.26)
点击右上角即可分享
微信分享提示