美文网首页动态规划信息学竞赛题解(IO题解)
BZOJ-1037: [ZJOI2008]生日聚会Party(D

BZOJ-1037: [ZJOI2008]生日聚会Party(D

作者: AmadeusChan | 来源:发表于2018-10-03 17:26 被阅读19次

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

    动态规划:

    状态:f(i,j,x,y)表示已经选取好了1..i的人,然后有j个男生,从某一位置起到i的序列中男生比女生最多多x人,女生比男生最多多y人,(x,y>=0),然后状态转移:

    f(i+1,j+1,x+1,y-1)+=f(i,j,x,y) 第i+1是男生 (x+1<=k,j+1<=n)

    f(i+1,j,x-1,y+1)+=f(i,j,x,y) 第i+1是女生(y+1<=k,i+1-j<=m)

    (貌似说空间没有丧心病狂地卡到要滚动数组啊,为什么网上大神们都这么说...)

    代码:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
     
    using namespace std;
     
    #define MAXN 151
    #define MAXK 21
    #define inf 0x7fffffff
    #define MAX 12345678
     
    int n,m,k,f[MAXN+MAXN][MAXN][MAXK][MAXK];
     
    int main() {
        scanf("%d%d%d",&n,&m,&k);
        memset(f,0,sizeof(f));
        f[0][0][0][0]=1;
        for (int i=0;i<n+m;i++) {
            for (int j=0;j<=n;j++) {
                for (int x=0;x<=k;x++) {
                    for (int y=0;y<=k;y++) {
                        if (f[i][j][x][y]) {
                            if (x+1<=k&&j+1<=n) {
                                f[i+1][j+1][x+1][max(y-1,0)]+=f[i][j][x][y];
                                f[i+1][j+1][x+1][max(y-1,0)]%=MAX;
                            }
                            if (y+1<=k&&i+1-j<=m) {
                                f[i+1][j][max(x-1,0)][y+1]+=f[i][j][x][y];
                                f[i+1][j][max(x-1,0)][y+1]%=MAX;
                            }
                        }
                    }
                }
            }
        }
        int ans=0;
        for (int i=0;i<=n;i++) {
            for (int x=0;x<=k;x++) {
                for (int y=0;y<=k;y++) {
                    ans+=f[n+m][i][x][y];
                    ans%=MAX;
                }
            }
        }
        printf("%d\n",ans);
        return 0;
    }
    

    相关文章

      网友评论

        本文标题:BZOJ-1037: [ZJOI2008]生日聚会Party(D

        本文链接:https://www.haomeiwen.com/subject/pqttaftx.html