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

对于30%的数据,n , m ≤ 20;对于100%的数据, n , m ≤ 150,k ≤ 20。

裸dp,f[a,b,c,d]表示有a个女的,b个男的,以最后一个人为右端点的女的最多比男的多c个,男的最多比女的多d个

(你要问我为什么这样表示,为什么第一维不是长度,我只能说Wikioi的云IDE内存不够大,况且我习惯用广度优先搜索,这样表示没有浪费空间,如果第一维是长度,那a<b的那一部分就用不到了,很浪费)

 1 const
 2     h=12345678;
 3     maxq=150*20*20*10;
 4 type
 5     point=record
 6       a,b,c,d:longint;
 7     end;
 8 var
 9     f:array[0..150,0..150,0..20,0..20]of longint;
10     q:array[0..maxq]of point;
11     n,m,k,head,tail,ans:longint;
12  
13 function max(x,y:longint):longint;
14 begin
15     if x>y then exit(x);
16     exit(y);
17 end;
18  
19 procedure main;
20 begin
21     read(n,m,k);
22     head:=1;
23     tail:=2;
24     fillchar(f,sizeof(f),1);
25     f[0,0,0,0]:=1;
26     while head<>tail do
27       begin
28         with q[head] do
29         if (a=n) and (b=m) then ans:=(ans+f[a,b,c,d])mod h
30         else
31           begin
32             if (a<n) and (c<k) then
33             begin
34               if f[a+1,b,c+1,max(0,d-1)]>h then
35               begin
36                 q[tail].a:=a+1;
37                 q[tail].b:=b;
38                 q[tail].c:=c+1;
39                 q[tail].d:=max(0,d-1);
40                 f[a+1,b,c+1,max(0,d-1)]:=0;
41                 tail:=tail mod maxq+1;
42               end;
43               f[a+1,b,c+1,max(0,d-1)]:=(f[a+1,b,c+1,max(0,d-1)]+f[a,b,c,d])mod h;
44             end;
45             if (b<m) and (d<k) then
46             begin
47               if f[a,b+1,max(0,c-1),d+1]>h then
48               begin
49                 q[tail].a:=a;
50                 q[tail].b:=b+1;
51                 q[tail].c:=max(0,c-1);
52                 q[tail].d:=d+1;
53                 f[a,b+1,max(0,c-1),d+1]:=0;
54                 tail:=tail mod maxq+1;
55               end;
56               f[a,b+1,max(0,c-1),d+1]:=(f[a,b+1,max(0,c-1),d+1]+f[a,b,c,d])mod h;
57             end;
58           end;
59         head:=head mod maxq+1;
60       end;
61     write(ans);
62 end;
63  
64 begin
65     main;
66 end.
View Code
原文地址:https://www.cnblogs.com/Randolph87/p/3650157.html