hdu 12310 girl friend #DP#组合数学

来源:互联网 发布:淘宝热区代码 编辑:程序博客网 时间:2024/06/06 05:24

http://acm.hnu.cn/online/?action=problem&type=show&id=12310&courseid=215


千万记得用64bit

//求一串不同颜色珠子(珠子的独特性只由颜色决定)的组合数#include <stdio.h>#include <string.h>#include <algorithm>#define N 10001#define NN 1001#define K 201#define MODE 1000000007__int64 c[N][K];void cal_c(){    int i,j;    for(i = 0; i < K; ++ i)        c[i][0] = 1;    for(i = 1; i < K; ++i)    {        for(j = 1; j <= i; ++j)            c[i][j] = (c[i-1][j] + c[i-1][j-1]) % MODE;    }}int n,k;int bead[N],used[N],cnt[NN],s[NN],su[NN];__int64 sum,dp[NN][K];int main(){    cal_c();    while(scanf("%d%d",&n,&k) != EOF)    {        memset(cnt,0,sizeof(cnt));        memset(dp,0,sizeof(dp));        int i,j,mk,ii;        for(i = 0; i < n; ++i)            scanf("%d",&bead[i]);        for(i = 0; i < n; ++i)        {            scanf("%d",&used[i]);            if(used[i])                cnt[bead[i]]++;        }        int sp = 0;        for(i = 0; i < 1001; ++i)            if(cnt[i])                s[sp++] = cnt[i];        su[0] = s[0];        for(i = 1; i < sp; ++i)            su[i] = su[i-1] + s[i];        if(su[sp-1] < k)        {            printf("0\n");            continue;        }        for(i = 0; i <= s[0]; ++i)            dp[0][i] = 1;        for(i = 1; i < sp; ++i)        {            for(j = 0;j <= su[i]&&j <= k; ++j)            {                sum = 0;                mk = std::min(j,s[i]);                for(ii = 0; ii <= mk; ++ii)///用ii个第i种 取代前i-1种j个情况 中的ii个                    sum = (sum + dp[i-1][j-ii]*c[j][ii]%MODE) % MODE;                dp[i][j] = sum;            }        }        printf("%I64d\n",dp[sp-1][k]);    }    return 0;}

原创粉丝点击