博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

[spoj][11574][A Famous Stone Collector]

Posted on 2012-07-16 19:01  紫华弦筝  阅读(248)  评论(0编辑  收藏  举报

题目:http://www.spoj.pl/problems/STONE2/

用生成函数的方法,其实也是dp的思想。

View Code
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int mod = 1000000007;
const int N = 105;

#define M(a) ((a)%mod)
#define ll long long
ll ans, an[N], n, all;
ll t1[N*N], t2[N*N], c[N*N][N];

void init(){
    memset(c,0,sizeof(c));c[0][0]=1;
    for (int i=1; i<=10000; i++){
        c[i][0] = 1;
        for (int j=1; j<=min(i,100); j++)
            c[i][j] = M(c[i-1][j-1]+c[i-1][j]);
    }
}
int cas=1;
int main(){
    //freopen("D:/a.txt", "r", stdin);
    init();
    while (~scanf("%lld", &n)){
        all = ans = 0;
        memset(t1, 0, sizeof(t1));
        t1[0]=t2[0]=1;
        for (int i=1; i<=n; i++) scanf("%lld", &an[i]);
        for (int i=1; i<=n; i++){
            memset(t2,0,sizeof(t2));
            for (int j=0; j<=all; j++){
                for (int k=0; k<=an[i]; k++){
                    t2[k+j]=M(t2[k+j]+M(t1[j]*c[k+j][k]));
                }
            }
            all += an[i];
            for (int j=0; j<=all; j++)
                t1[j] = t2[j];
        }
        for (int i=1; i<=all; i++)
            ans = M(ans+t1[i]);
        printf("Case %d: %lld\n", cas++, ans);
    }
    return 0;
}