1037: [ZJOI2008]生日聚会Party
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
对于100%的数据, n , m ≤ 150,k ≤ 20。
用F[i][j][k1][k2]表示前i个人中有j个男生,其中男生最多比女生k1个,女生最多比男生多k2个
然后对于第i+1个人,有两种情况:
1.当他是男生时:F[i+1][j+1][k1+1][k2-1]+=F[i][j][k1][k2](注意:当k2-1<0时k2-1=0)
2.当他是女生时:F[i+1][j][k1-1][k2+1]+=F[i][j][k1][k2]
然后就可以做了。。。
然后我们可以发现这道题的表示前i个人的状态每次只涉及到i和i+1然后可以考虑滚动数组,然后去掉这个状态,就可以省内存了。。。
不过我并没有用。。。=,=
4 #include<iostream> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cstring> 8 #include<cstdio> 9 #include<algorithm> 10 #include<string> 11 #include<map> 12 #include<queue> 13 #include<vector> 14 #include<set> 15 #define inf 1000000000 16 #define eps 1e-10 17 #define mod 12345678 18 #define maxn 150+5 19 #define maxm 20+5 20 #define ll long long 21 #define for0(i,n) for(int i=0;i<=(n);i++) 22 #define for1(i,n) for(int i=1;i<=(n);i++) 23 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 24 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 25 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go) 26 using namespace std; 27 int f[310][maxn][maxm][maxm]; 28 int read(){ 29 int x=0,f=1;char ch=getchar(); 30 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 31 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 32 return x*f; 33 } 34 int main(){ 35 //freopen("input.txt","r",stdin); 36 //freopen("output.txt","w",stdout); 37 int n=read(),m=read(),k=read(); 38 f[0][0][0][0]=1; 39 for0(i,n+m) 40 for0(j,min(i,n)) 41 for0(k1,min(min(i,j),k)) 42 for0(k2,min(min(i,i-j),k)){ 43 if(k1<k&&j<n)f[i+1][j+1][k1+1][max(k2-1,0)]=(f[i][j][k1][k2]+f[i+1][j+1][k1+1][max(k2-1,0)])%mod; 44 if(k2<k&&(i-j)<m)f[i+1][j][max(k1-1,0)][k2+1]=(f[i][j][k1][k2]+f[i+1][j][max(k1-1,0)][k2+1])%mod; 45 } 46 int ans=0; 47 for0(i,k) 48 for0(j,k) 49 ans=(ans+f[n+m][n][i][j])%mod; 50 printf("%d",ans); 51 return 0; 52 }