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。
题解:
首先,冒出来是dp,然而,发现我的方程和题解不一样。。。
dp[i][j][a][b]中,i表示目前搞定i个人,j表示放进来多少男孩,a表示从后往前最多男孩比女孩多a个,b表示从后往前最多女孩比男孩多b个。(因为在末端加入孩子,对中间男女数量之差没有影响)
code:(粘了别人的)
#include<cstdio>
#include<algorithm>
#include<cstring>
using
namespace
std
;
#define inf 0x7fffffff
#define mod 12345678
int
n
,
m
,
k
,
f
[
301
]
[
151
]
[
21
]
[
21
]
;
int
main
(
)
{
scanf
(
"%d%d%d"
,
&n
,
&m
,
&k
)
;
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
)
]
%=
mod
;
}
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
]
%=
mod
;
}
}
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
%=
mod
;
}
printf
(
"%d\n"
,
ans
)
;
return
0
;
}