[ZJOI]2008 生日聚会

Posted guoyangfan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[ZJOI]2008 生日聚会相关的知识,希望对你有一定的参考价值。

技术图片

 


 

显然DP。

将题目转化下: 求由n个0、m个1组成,且满足任意子串0的数量和1的数量差绝对值不超过k的01串数量。n, m≤150,k≤20。

直接做没什么思路,,那我们尽量利用题目的时间和空间限制,以达到清晰、方便的方程转移。

 


 

 

由于题目n、m很小,可以考虑O(nm)带k的几次方的算法。

设f[a][b][l][h]表示当前序列中放了a个1,b个0,所有后缀中,男生减女生的差最大为l,女生减男生的差最大为h的方案数。

那么状态转移显然->  f[a][b][l][h] 可以向 f[a+1][b][l+1][max(h-1),0] 或 f[a][b+1][max(l-1)][h+1] 转移;最后答案统计f[n][m][l][h](枚举l,h)。

 

Code:

#include<bits/stdc++.h>
using namespace std;

const int maxn = 180;
const int mod = 12345678;

int f[maxn][maxn][26][26];

int main()
    int n,m,k;
    cin>>n>>m>>k;
    f[0][0][0][0] = 1;
    for(int a = 0;a<=n;++a)
    for(int b = 0;b<=m;++b)
    for(int l = 0;l<=k;++l)
    for(int h = 0;h<=k;++h)
    if(f[a][b][l][h])
        int cnt = f[a][b][l][h];
        f[a+1][b][l+1][max(h-1,0)] += cnt;f[a+1][b][l+1][max(h-1,0)]%=mod;
        f[a][b+1][max(l-1,0)][h+1] += cnt;f[a][b+1][max(l-1,0)][h+1]%=mod;
    
    int ans = 0;
    for(int i = 0;i<=k;++i)
        for(int j = 0;j<=k;++j)
        ans = (ans + f[n][m][i][j])%mod;
    cout<<ans<<endl;

 

 

 

 

 

以上是关于[ZJOI]2008 生日聚会的主要内容,如果未能解决你的问题,请参考以下文章

[BZOJ 1037][ZJOI2008]生日聚会Party

bzoj1037: [ZJOI2008]生日聚会Party

1037: [ZJOI2008]生日聚会Party

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

bzoj 1037: [ZJOI2008]生日聚会Party

[ZJOI2008]生日聚会