【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; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 深入理解 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)