题意
给
n
n
n个孩子发
k
k
k颗糖,每个孩子最多拿到
a
i
a_i
ai颗,问有多少种分法.
n
≤
100
,
k
≤
1
0
5
n\leq 100,k\leq 10^5
n≤100,k≤105.
题解
考虑
d
p
.
dp.
dp.
非常裸的
d
p
dp
dp如下.
for (int i=1;i<=n;++i) {
for (int j=k;~j;--j)
for (int l=j+1;l<=j+a[i];++l)
dp[l]=(dp[l]+dp[j])%mod;
}
复杂度为
O
(
n
×
k
2
)
O(n \times k^2)
O(n×k2),显然不能通过.
令
d
p
j
dp_j
dpj为前
i
i
i(滚动数组)个孩子有
k
k
k颗糖没有发到的总分法数.
假设当前的孩子最多能够分到
k
k
k颗糖而不是
a
i
a_i
ai颗,则
d
p
k
=
上
一
个
d
p
k
dp_k=上一个dp_k
dpk=上一个dpk(这个孩子没分到糖).
d
p
k
−
1
=
上
一
个
d
p
k
−
1
+
d
p
k
dp_{k-1}=上一个dp_{k-1}+dp_k
dpk−1=上一个dpk−1+dpk(这个孩子可以分到一颗糖,也可以不分到糖).
以此类推,
d
p
0
=
上
一
个
d
p
0
+
d
p
1
+
.
.
.
+
d
p
k
−
1
+
d
p
k
dp_0=上一个dp_0+dp_1+...+dp_{k-1}+dp_k
dp0=上一个dp0+dp1+...+dpk−1+dpk.
但是实际上这个孩子最多只能分到
a
i
a_i
ai颗糖,因此我们要把超过
a
i
a_i
ai的部分减掉.
由于刚才已经做过前缀和,对
j
j
j只需要减掉
d
p
j
+
a
i
+
1
dp_{j+a_i+1}
dpj+ai+1这个位置的答案就可以了.
这样一来本题就解决了.
谢谢大家.
const int yuzu=2e5,mod=1e9+7;
typedef ll fuko[yuzu|10];
fuko dp;
int main() {
int i,n,k,a;
read(n),read(k);
for (dp[k]=1;read(a);) {
for (i=k;i--;) dp[i]+=dp[i+1];
for (i=0;i<k;++i) dp[i]=(dp[i]-dp[i+a+1])%mod;
}
printf("%lld\n",*dp);
}