1. 程式人生 > >poj 3046 多重集組合數【水一下】

poj 3046 多重集組合數【水一下】

題目大意:有t個螞蟻種群,共a只螞蟻,從這些種群中挑出n只螞蟻,方法共有x[n]種,計算x[s]+x[s+1]+…+x[b]。
這是一道多重集組合數題目。用dp[i][j]表示前i中種群中挑出j只螞蟻的方案數。依據《挑戰程式競賽(第二版)》 P68-P69公式。
程式碼如下:

#include<iostream>
#include<cstdio>
#define M 1000000
using namespace std;


int dp[1005][100005];


int main()
{
    int t,s,b,a;
    int group[1005];
    scanf
("%d%d%d%d",&t,&a,&s,&b); for(int i=1;i<=t;i++) group[i]=0; for(int i=0;i<a;i++) { int m; scanf("%d",&m); group[m]++; } for(int i=0;i<t;i++) { dp[i][0]=1; } for(int i=0;i<t;i++) { for(int j=0
;j<=b;j++) if(j>group[i+1]) dp[i+1][j]=(dp[i+1][j-1]+dp[i][j]-dp[i][j-1-group[i+1]]+M)%M; else dp[i+1][j]=(dp[i+1][j-1]+dp[i][j])%M; } int ans=0; for(int i=s;i<=b;i++) ans=(ans+dp[t][i])%M; printf("%d\n",ans); }