[BZOJ] 1037 [ZJOI2008]生日聚會

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 3007  Solved: 1795
[Submit][Status][Discuss]
Description
  今天是hidadz小朋友的生日,她邀請了許多朋友來參加她的生日party。 hidadz帶着朋友們來到花園中,打算
坐成一排玩遊戲。爲了遊戲不至於無聊,就座的方案應滿足如下條件:對於任意連續的一段,男孩與女孩的數目之
差不超過k。很快,小朋友便找到了一種方案坐了下來開始遊戲。hidadz的好朋友Susie發現,這樣的就座方案其實
是很多的,所以大家很快就找到了一種,那麼到底有多少種呢?熱愛數學的hidadz和她的朋友們開始思考這個問題
…… 假設參加party的人中共有n個男孩與m個女孩,你是否能解答Susie和hidadz的疑問呢?由於這個數目可能很
多,他們只想知道這個數目除以12345678的餘數。

Input
  僅包含一行共3個整數,分別爲男孩數目n,女孩數目m,常數k。

Output
  應包含一行,爲題中要求的答案。

Sample Input
1 2 1
Sample Output
1
HINT
n , m ≤ 150,k ≤ 20。

神奇的思路,自己沒想到pup。。。
f[i][j][x][y]表示前i個人,有j個男生,且男生最多比女生多x個,女生最多比男生多y個

轉移的時候用已知刷未知

#include <bits/stdc++.h>
#define rep(i,j,k) for(register int i=j;i<=k;i++)
#define dow(i,j,k) for(register int i=j;i>=k;i--)
#define ez(i,x) for(register int i=h[x];i;i=e[i].n)
#define MP make_pair

using namespace std;

inline int read(){
    register char ch='*';int f=1;
    while(!isdigit(ch=getchar())) if(ch=='-') f=-1;register int x=ch-'0';
    while(isdigit(ch=getchar())) x=x*10+ch-'0';
    return x*f;
}

int n,m,k;

const int MOD=12345678;

int f[305][155][21][21];

int main(){
    n=read();
    m=read();
    k=read();
    f[0][0][0][0]=1;
    rep(i,0,n+m) rep(j,0,n) rep(x,0,k) rep(y,0,k){
        if(f[i][j][x][y]){
            if(j+1<=n&&x+1<=k) (f[i+1][j+1][x+1][max(y-1,0)]+=f[i][j][x][y]%MOD)%MOD;
            if(i-j+1<=m&&y+1<=k) (f[i+1][j][max(x-1,0)][y+1]+=f[i][j][x][y]%MOD)%MOD;
        }
     }
    int ans=0;
    rep(i,0,k) rep(j,0,k) ans+=f[n+m][n][i][j],ans%=MOD;
    cout<<ans;
    return 0;   
}



發佈了180 篇原創文章 · 獲贊 6 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章