bzoj 1037 [ZJOI2008]生日聚会Party(DP)

时间:2023-03-09 03:48:11
bzoj 1037 [ZJOI2008]生日聚会Party(DP)

【题目链接】

http://www.lydsy.com/JudgeOnline/problem.php?id=1037

【题意】

一排n男m女,求满足任意连续段男女人数之差不超过k的数目。

【思路】

DP

设f[a][b][c][d]表示a男b女,男生女生人数最大差为c,女生男生人数最大差为d的方案数,则有转移方程:

    f[a+1][b][c+1][max(d-1,0)]<-f[a][b][c][d]

    f[a][b+1][max(c-1,0)][d+1]<-f[a][b][c][d]

  太神辣 -<

【代码】

 #include<cstdio>
#include<iostream>
#define FOR(a,b,c) for(int a=b;a<=c;a++)
using namespace std; const int N = ;
const int MOD = ; int f[N][N][][];
int n,m,K; int main()
{
scanf("%d%d%d",&n,&m,&K);
f[][][][]=;
FOR(a,,n) FOR(b,,m)
FOR(c,,K) FOR(d,,K)
if(f[a][b][c][d]) {
if(a<n&&(c<K)) {
f[a+][b][c+][max(d-,)]=(f[a+][b][c+][max(d-,)]+f[a][b][c][d])%MOD;
}
if(b<m&&d<K) {
f[a][b+][max(c-,)][d+]=(f[a][b+][max(c-,)][d+]+f[a][b][c][d])%MOD;
}
}
int ans=;
FOR(c,,K) FOR(d,,K)
ans=(ans+f[n][m][c][d])%MOD;
printf("%d\n",ans);
}