AT_dp_m Candies题解
题目描述
有 N 个孩子。孩子们被编号为 1,2,…,N。
他们要一起分配 K 颗糖果。此时,对于每个 i(1≤i≤N),第 i 个孩子能分到的糖果数必须在 0 到 ai 之间(包含 0 和 ai)。此外,所有糖果必须全部分完,不能有剩余。
请问有多少种不同的分配糖果的方法?请输出答案对 109+7 取模后的结果。这里,若存在某个孩子分到的糖果数不同,则认为两种分配方法不同。
输入格式
输入以如下格式从标准输入给出。
N K a1 a2 … aN
输出格式
输出分配糖果的方法数对 109+7 取模后的结果。
显示翻译
题意翻译
输入输出样例
输入 #1复制
3 4 1 2 3
输出 #1复制
5
输入 #2复制
1 10 9
输出 #2复制
0
输入 #3复制
2 0 0 0
输出 #3复制
1
输入 #4复制
4 100000 100000 100000 100000 100000
输出 #4复制
665683269
说明/提示
限制条件
- 所有输入均为整数。
- 1≤N≤100
- 0≤K≤105
- 0≤ai≤K
样例解释 1
分配糖果的方法共有 5 种。对于每个序列,第 i 个元素表示第 i 个孩子分到的糖果数。
- (0,1,3)
- (0,2,2)
- (1,0,3)
- (1,1,2)
- (1,2,1)
样例解释 2
也有可能不存在任何一种分配糖果的方法。
样例解释 3
分配糖果的方法只有 1 种。
- (0,0)
样例解释 4
不要忘记将答案对 109+7 取模后输出。
由 ChatGPT 4.1 翻译
思路
直接DP。
代码见下
#include<bits/stdc++.h>
using namespace std;
//long long d=1e7,wl[]={9,2,5,5,4,5,6,3,7,6};
//long long f[101][100001];
//long long z[1000003],sd,g[1000003],o[1000300],uss[501][501],q,ev,egeg=0,wsws=0,ld[1000001];
//long long n,m,mo=1e9+7;
//long long s=10;
//long long sf=1,sg=s,sh=-1313333,tt=9e8,l,k,b1,b2,b3,b4;
//char iio;
struct ll{
long long a,b,c,d,e,k,x,y,z;
}v[102345];
bool qp(ll a,ll b){
return a.a<b.a;
}
long long mo=1e9+7,f[105][100005],ld[100005],lk=0,n,m,z[105];
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>z[i];
}
f[0][0]=1;
for(int i=1;i<=n;i++){
ld[0]=f[i-1][0];
for(int k=1;k<=m;k++){
ld[k]=(ld[k-1]+f[i-1][k])%mo;
}
for(int j=0;j<=m;j++){
f[i][j]=(ld[j]+mo-ld[max(lk,j-z[i])-1])%mo;
}
}
cout<<f[n][m]<<endl;
return 0;
}

浙公网安备 33010602011771号