Loading

DP Training M 简单计数DP

DP Training M 简单计数DP

题意

\(N\)个孩子分\(K\)个糖果,第\(i\)个孩子分到的糖果要在\(0\)\(a_i\)之间

求分配的方案数,模1e9+7

\[1 \leq N \leq 100\\ 0 \leq K \leq 10^5\\ 0\leq a_i \leq K \]

分析

看数据量容易想到\(dp[i][j]\)表示当前枚举到第\(i\)个人,要掉\(j\)个糖果的方案数

\[dp[i][j] = \sum dp[i - 1][j - k] \]

复杂度\(O(nk^2)\)

显然后面是连续的和,可以前缀和优化

空间上,第一维明显可以滚动

代码

ll dp[maxn];
ll a[maxn],sum[maxn];

int main(){
	int n = rd();
	int k = rd();
	for(int i = 0;i < n;i++)
		a[i] = rd();
	dp[0] = 1ll;
	for(int i = 1;i <= n;i++){
		sum[0] = 0;
		for(int j = 1;j <= k + 1;j++) 
			sum[j] = sum[j - 1] + dp[j - 1];
		for(int j = 1;j <= k;j++)
			dp[j] = sum[j + 1] - sum[max(0ll,(ll)j - a[i - 1])],dp[j] %= MOD;
	}
	cout << dp[k];
} 
posted @ 2021-02-06 11:33  MQFLLY  阅读(91)  评论(0编辑  收藏  举报