bzoj1037: [ZJOI2008]生日聚会Party

被数位DP虐爆,迁怒于DP

然而这题我一开始的想法是f[i][j][k][l]表示到第i位置,用了j个男生,k个女生,到当前位置差别最大为l

但其实男生女生是可以合成一维的,然后后面两维应该是max(男 - 女)和max(男 - 女)

转移也不难

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int mod=12345678;
int f[2][210][30][30];
int main()
{
    int n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    
    int pre=0,now=1;
    memset(f,0,sizeof(f));f[now][0][0][0]=1;
    for(int i=0;i<=n+m-1;i++)
    {
        for(int j=0;j<=n;j++)
            for(int a=0;a<=k;a++)
                for(int b=0;b<=k;b++)
                    if(f[now][j][a][b]!=0)
                    {
                        if(a+1<=k&&j+1<=n)
                            f[pre][j+1][a+1][max(b-1,0)]=(f[pre][j+1][a+1][max(b-1,0)]+f[now][j][a][b])%mod;
                        if(b+1<=k&&i+1-j<=m)
                            f[pre][ j ][max(a-1,0)][b+1]=(f[pre][ j ][max(a-1,0)][b+1]+f[now][j][a][b])%mod;
                    }
        swap(pre,now);
        memset(f[pre],0,sizeof(f[pre]));
    }
    
    int ans=0;
    for(int a=0;a<=k;a++)
        for(int b=0;b<=k;b++)
            ans=(ans+f[now][n][a][b])%mod;
    printf("%d
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/AKCqhzdy/p/8794759.html