HDU 5209 Magic Toy Brick

来源:互联网 发布:unity3d建筑可视化 编辑:程序博客网 时间:2024/06/08 03:13

很好的一道dp题

首先可以推算出一行之中放n个最大m时的方案数为C(n+m-1,n)

设dp[n]表示n行的方案数 首先第一行 的第一个数应该是最小的 第一行的其他数是任意的 所以这一行取j个数时 的方案为C(n-1,j) * dp[n-j-1] (下面一行遵从同意的规则)

当时做的时候脑子抽了 写了个dfs以为是n²的 结果T了 调试了半天 才发那是n!的(>﹏<)  

#include<iostream>#include<cstdio>#include<cstring>#include<cctype>#include<cmath>#include<vector>#include<queue>#include<map>#include<algorithm>#include<set>#define scnaf scanf#define cahr char#define bug puts("bugbugbug");using namespace std;typedef long long ll;const int mod=1000000007;const int maxn=101000+50;const int maxe=200000;ll fac[maxn], inv[maxn],ans;int n,m,X[1005]={1},Y[1005]={1},a[1005];ll powMod(ll a, ll b){    ll ans=1;    while(b)    {        if(b&1)            ans=ans*a%mod;        a=a*a%mod;        b>>=1;    }    return ans;}void init_c(){    int maxn=101000;    fac[0]=1;    for(int i=1; i<=maxn; i++)        fac[i]=fac[i-1]*i%mod;    inv[maxn]=powMod(fac[maxn],mod-2);    for(int i=maxn-1; i>=0; i--)        inv[i]=inv[i+1]*(i+1)%mod;}int c(int n,int m){    return fac[n]*inv[m]%mod*inv[n-m]%mod;}inline void RDF(int &ret) { //输入为负数    char c;    int sgn;    while(c != '-' && (c < '0' || c > '9')) c = getchar();    sgn = (c == '-') ? -1 : 1;    ret = (c == '-') ? 0 : (c - '0');    while(c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');    ret *= sgn;}inline void RD(int &ret) { //输入为整数    char c;    do {        c = getchar();    } while(c < '0' || c > '9');    ret = c - '0';    while((c = getchar()) >= '0' && c <= '9') {        ret = ret * 10 + (c - '0');    }}inline void OT(int a) { //输出为正数    if(a >= 10) {        OT(a / 10);    }    putchar(a % 10 + '0');}int T_T,test=1;ll dp[1005];void print(){    putchar('C');putchar('a');putchar('s');putchar('e');putchar(' ');putchar('#');    OT(test++); putchar(':');putchar(' '); OT(ans);putchar('\n');}int main(){    init_c();    RD(T_T);    while(T_T--){        ans=0;        RD(n);RD(m);        for(int i=1;i<=n;i++){            X[i]=c(i+m-1,i);        }        dp[0]=1;        for(int i=1;i<=n;i++){            dp[i]=0;            for(int j=0;j<=i-1;j++)            dp[i]=(dp[i]+c(i-1,j)*dp[i-1-j]%mod*X[j+1])%mod;        }        ans=dp[n];       print();    }    return 0;}


0 0
原创粉丝点击