SOJ 3531_Number Pyramids

【题意】给定一个数top及最底层元素个数n,构成一个以给top为塔尖,层数为n的如杨辉三角的金字塔,求有多少种

【分析】最终种数其实只与最底层的n个数的组合数有关,上层的每个都数是由最底层数相加得来

以层数4为例

设最底层 x1x2x3x4

则第二层x1+x2x2+x3x3+x4

第三层x1+2*x2+x3 x2+2*x3+x4

最高层 x1+3*x2+3*x3+x4

可以看出  1 3 3 1   C(3,0) C(3,1) C(3,2) C(3,3)

所以问题可以看做是一个以 C(n-1,0) C(n-1,1).....C(n-1,n)为单个物品容量,容量和为2^(n-1),top为背包总容量的完全背包问题,其中由于最底层数均大于一,所以每个背包至少被装一次。

又由于背包最大有10^6,所以n应小于20

【代码】

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
int v[1000050];
int c[1000050];
using namespace std;
int length,top,total;
const int mod=1000000009;
void init(int n)
{
    total=1;
    memset(c,0,sizeof(c));
    c[0]=1;
    for(int i=1;i<=n;i++)
    {
        c[i]=c[i-1]*(n+1-i)/i;
        total+=c[i];
    }

}
int main (void)
{
    while(scanf("%d%d",&length,&top)==2)
    {
        if(length>20)
        {
            printf("0
");
            continue;
        }
        init(length-1);
        if(top<total)
        {
            printf("0
");
            continue;
        }
        memset(v,0,sizeof(v));
        v[0]=1;
        for(int i=0;i<length;i++)
        {
            for(int j=c[i];j<=top-total;j++)
                v[j]=(v[j]+v[j-c[i]])%mod;
        }

        printf("%d
",v[top-total]%mod);
    }
    return 0;

}
最初想的是每一层的元素都是由该层第一个数决定,所以只需找出每层第一个数组成的排列种数,可是不会写代码,写了个递归可是组合数稍微大一点就慢死。

所以弱渣还是要多观察多思考。

原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758879.html