bzoj4806 炮——DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4806
看到这题首先会想到状压什么乱七八糟的,然而很难做;
其实,因为求的是方案数,所以并不需要关注炮摆放的位置,而只需要关注数量;
f[i][j][k] 表示第 i 行及以前共有 j 个有 0 炮的列和 k 个有 1 炮的列,就可以转移了。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; int const mod=999983,maxn=105; ll n,m,f[maxn][maxn][maxn],ans; ll C(ll x){return ((x-1)*x/2)%mod;}//不是(x+1) !! int main() { scanf("%d%d",&n,&m); f[0][m][0]=1; for(int i=1;i<=n;i++) for(int j=0;j<=m;j++)//0 for(int k=0;k<=m-j;k++)//1 { (f[i][j][k]+=f[i-1][j][k])%=mod;//放0个 if(k>=0&&j<m)(f[i][j][k]+=f[i-1][j+1][k-1]*(j+1))%=mod;//0 -> 1 //别写成 if(k&&j<m) !! if(k<m)(f[i][j][k]+=f[i-1][j][k+1]*(k+1))%=mod;//1 -> 2 if(j<m)(f[i][j][k]+=f[i-1][j+1][k]*(j+1)*k)%=mod;//0 1 -> 1 2 if(k-2>=0&&j+2<=m)(f[i][j][k]+=f[i-1][j+2][k-2]*C(j+2))%=mod;//0 0 -> 1 1 if(k+2<=m)(f[i][j][k]+=f[i-1][j][k+2]*C(k+2))%=mod;//1 1 -> 2 2 } for(int j=0;j<=m;j++) for(int k=0;k<=m;k++) (ans+=f[n][j][k])%=mod; printf("%lld",ans); return 0; }
分类:
动规
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
· .NET 进程 stackoverflow异常后,还可以接收 TCP 连接请求吗?
· SQL Server统计信息更新会被阻塞或引起会话阻塞吗?
· 传国玉玺易主,ai.com竟然跳转到国产AI
· 本地部署 DeepSeek:小白也能轻松搞定!
· 自己如何在本地电脑从零搭建DeepSeek!手把手教学,快来看看! (建议收藏)
· 我们是如何解决abp身上的几个痛点
· 普通人也能轻松掌握的20个DeepSeek高频提示词(2025版)