题目描述
蚂蚁山上有T(1<=T<=1,000)种蚂蚁,标记为1…T,每种蚂蚁有N_i只蚂蚁(1<=N_i<=100),现有A(A<=5000)只蚂蚁,从中选出S,S+1,…,B(1<=S<=B<=A)只蚂蚁一共有多少种选法?
如有5只蚂蚁分别为{1,1,2,2,3},一共有3种蚂蚁,每一种蚂蚁的数量分别为2,2,1,以下是选不同数量蚂蚁的方法:
1个蚂蚁3种选法:{1}{2}{3}
2个蚂蚁5种选法:{1,1}{1,2}{1,3}{2,2}{2,3}
3个蚂蚁5种选法:{1,1,2}{1,1,3}{1,2,2}{1,2,3}{2,2,3}
4个蚂蚁3种选法:{1,2,2,3}{1,1,2,2}{1,1,2,3}
5个蚂蚁1种选法:{1,1,2,2,3}
你的任务是从中选S…B只蚂蚁的方法总和。
输入
第一行: 4个空格隔开的整数: T, A, S和B;
第2到A+1行:每行一个整数表示蚂蚁的种类。
输出
输出从A只蚂蚁中选出S…B只蚂蚁的方法数,答案保留后6位。
输入样例
3 5 2 3
1
2
2
1
3
输出样例
10
说明
对于30%的数据:T<=30,A<=100;
对于50%的数据:T<=100,A<=400;
对于100%的数据:T<=1000,A<=5000;
.
.
.
.
.
分析
.
.
.
.
.
程序:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int n,m,l,r,t,x[5005],f[1005][5005],s[1005][5005],mo=1000000;
int main()
{
scanf("%d%d%d%d",&n,&m,&l,&r);
for (int i=1;i<=m;i++)
{
int t;
scanf("%d",&t);
x[t]++;
}
for (int i=0;i<=m;i++)
s[1][i]=min(i,x[1])+1;
for (int i=2;i<=n;i++)
{
s[i][0]=1;
for (int j=1;j<=m;j++)
{
f[i][j]=(s[i-1][j]-s[i-1][j-min(x[i],j)-1])%mo;
s[i][j]=(s[i][j-1]+f[i][j])%mo;
}
}
int ans=0;
for (int i=l;i<=r;i++)
ans=(ans+f[n][i])%mo;
printf("%d",ans);
return 0;
}