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\ 0leq 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];
} 
原文地址:https://www.cnblogs.com/hznumqf/p/14381002.html