题目
大意是T种数,每种数有一定的数量,用这些数组成S到B的长度的集合,问有几种方法(具体意思看原题吧,我自己一开始读了好几遍都没弄懂)
千万别看漏了只需要6位这个输出要求,我WA了好几次才发现
算法
这道题看起来很像有限背包问题,用简单的DP算法就能解决。当然,由于这类题目第i-1个以前的数均无后效性,可以开2个一维数组组成的二维数组,使用滚动数组的思想,可以极大地降低空间复杂度。
题解
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
const int mod=1e6;
int a[111111],dp[2][111111];
using namespace std;
main()
{
int m,n,i,j,h,k,l,left,right;
cin>>n>>m>>left>>right;
for(i=1;i<=n;i++)
a[i]=0;
for(i=1;i<=m;i++)
{
int qwe;
cin>>qwe;
a[qwe]++;
}
for(i=0;i<=right;i++)
dp[1][i]=0;
for(i=0;i<=a[1];i++)
dp[1][i]++;
for(i=2;i<=n;i++)
{
for(j=0;j<=right;j++)
{
for(k=0;k<=min(a[i],right-j);k++)
{
dp[i%2][j+k]=(dp[(i-1)%2][j]+dp[i%2][j+k])%mod;//DP核心方程
}
dp[(i-1)%2][j]=0;
}
dp[i%2][0]=1;
}
int ans=0;
for(i=left;i<=right;i++)
ans=(dp[n%2][i]+ans)%mod;
cout<<ans<<endl;
return 0;
}