HYSBZ/BZOJ 1037 [ZJOI2008] 生日聚会Party - dp

题目描述

分析:

dp[i][j][p][q]表示前i个boy,j个girl,男孩数量-女孩数量的最大值为p,女孩数量-男孩数量的最大值为q。因为可能没有女孩或者男孩,p,q可能为负数,就用0表示(p,q是最大值,p,q为负的情况只有没有女孩或者没有男孩这种情况)

dp[i][j][p][q]=dp[i-1][j][p-1][q+1] + dp[i][j-1][p+1][q-1]
没办法填表,用刷表法:
dp[i][j][p][q] 影响 dp[i+1][j][p+1][q-1] 和 dp[i][j+1][p-1][q+1]

#include<cstdio>
#include<algorithm>
using namespace std;
#define Mod 12345678
#define MAXN 150
#define MAXK 20

int n,m,k,dp[MAXN+5][MAXN+5][MAXK+5][MAXK+5],ans;

int main()
{
    scanf("%d%d%d",&n,&m,&k);
    //dp[i][j][p][q] -> dp[i+1][j][p+1][q-1] , dp[i][j+1][p-1][q+1]
    dp[0][0][0][0]=1;
    for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++){
            for(int p=0;p<=k;p++)
                for(int q=0;q<=k;q++){
                    dp[i+1][j][p+1][max(q-1,0)]=(dp[i+1][j][p+1][max(q-1,0)]+dp[i][j][p][q])%Mod;
                    dp[i][j+1][max(p-1,0)][q+1]=(dp[i][j+1][max(p-1,0)][q+1]+dp[i][j][p][q])%Mod;
                }
        }
    for(int p=0;p<=k;p++)
        for(int q=0;q<=k;q++){
            ans=(ans+dp[n][m][p][q])%Mod;
    }
    printf("%d\n",ans%Mod);
}
posted @ 2016-02-05 14:53  KatarinaYuan  阅读(117)  评论(0编辑  收藏  举报