【BZOJ1037】[ZJOI2008]生日聚会(动态规划)
2024-09-18 00:46:16
【BZOJ1037】[ZJOI2008]生日聚会(动态规划)
题面
题解
假设前面的都合法,但是在加完当前的最后一个人之后变得不合法了,那么意味着一定有着一个后缀不合法。把男生看成\(1\),女生看成\(-1\),也就是不存在一个后缀和大于\(K\)或者一个后缀和小于\(-K\)。而在最后面加进一个男生或者女生显然就是把所有后缀\(+1\)或者\(-1\)。那么设\(f[i][j][k][l]\)表示当前考虑到了第\(i\)个位置,放了\(j\)个\(1\),最大的后缀和为\(j\),最小的后缀和为\(-l\)的方案数。转移的时候判断一下是否合法就好了。
时间复杂度\(O(n^2k^2)\)。
#include<iostream>
#include<cstdio>
using namespace std;
#define MOD 12345678
void add(int &x,int y){x+=y;if(x>=MOD)x-=MOD;}
int f[305][155][22][22];
int n,m,K,ans;
int main()
{
scanf("%d%d%d",&n,&m,&K);
f[0][0][0][0]=1;
for(int i=1;i<=n+m;++i)
for(int j=0;j<=i&&j<=n;++j)
for(int k=0;k<=K;++k)
for(int l=0;l<=K;++l)
{
if(!f[i-1][j][k][l])continue;
if(j<n&&k!=K)add(f[i][j+1][k+1][max(0,l-1)],f[i-1][j][k][l]);
if(i-j-1<m&&l!=K)add(f[i][j][max(0,k-1)][l+1],f[i-1][j][k][l]);
}
for(int k=0;k<=K;++k)
for(int l=0;l<=K;++l)
add(ans,f[n+m][n][k][l]);
printf("%d\n",ans);
return 0;
}
最新文章
- Web Application Penetration Testing Local File Inclusion (LFI) Testing Techniques
- iOS 私有变量 私有方法
- Swap Nodes in Pairs
- checkbox全选,反选,取消选择 jquery
- chrome常用配置
- python中的模块
- cacti批量添加主机脚本
- js字符串处理
- Linux删除包含特殊符号文件名的文件
- c# 发送消息到Email
- ExtJs4.2 知识点
- java日志,(commons-loging 、log4j 、slf4j 、LogBack介绍)
- 『奇葩问题集锦』Malformed lock file found: /var/cache/dnf/metadata_lock.pid.
- Navicat Premium 未保存的SQL如何找回 ?
- 解决asp.net中“从客户端中检测到有潜在危险的Request.Form值”的错误
- mysql创建定时任务,每月1号删除上月数据
- 扩展Microsoft Graph数据结构 - 架构扩展
- 使用 boot-repair 对 Windows + Ubuntu 双系统引导修复
- LOJ #6268 分拆数
- Linux 各种软件的安装-mediawiki + wordpress篇