BZOJ1037&&洛谷P2592 [ZJOI2008]生日聚会

四重循环大模拟

我们考虑f[i][j][k][e]表示前i个人,有j个男生,女生个数即为i-j,任意一段中男生最多比女生多k个,女生比男生最多多e个,

那么当前状态可以转移到

1.在j<n的情况下,下一个人是男生,即f[i+1][j+1][k+1][e-1],因为e可能是负数,然后我们就不管他了,负数全看成0,然后直接转移过去

2.在i-j<m,下一个人是女生,即f[i+1][j][k-1][e+1],同男生,k可能是负数,也看成0,然后直接转移接好了

代码

//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm> 
using namespace std;
const int M=160;
const int mod=12345678;
int n,m,e;
int f[M*2][M][21][21];
signed main()
{
	cin>>n>>m>>e;f[0][0][0][0]=1;
	for (int i=0;i<=n+m-1;i++)
	for (int j=0;j<=n;j++)
	for (int k=0;k<=e;k++)
	for (int o=0;o<=e;o++)
	if (f[i][j][k][o])
	{
		if (j+1<=n&&k+1<=e)
		f[i+1][j+1][k+1][max(o-1,0)]=(f[i+1][j+1][k+1][max(o-1,0)]+f[i][j][k][o])%mod;
		if (i+1-j<=m&&o+1<=e) 
		f[i+1][j][max(k-1,0)][o+1]=(f[i+1][j][max(k-1,0)][o+1]+f[i][j][k][o])%mod;
	}
	int ans=0;
	for (int i=0;i<=e;i++)
	for (int k=0;k<=e;k++)
	ans=(ans+f[n+m][n][i][k])%mod;
	cout<<ans;
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值