-->

现哥的摩天大厦 乘法原理

本文为博主原创文章,如转载,请标明出处www.cnblogs.com/yangyaojia

现哥的摩天大厦(tall.pas/c/cpp)

Time Limit:1s  Memory Limit:256MB

【题目描述】

现哥准备从现在从没钱开始攒钱建座摩天大厦!1秒……2秒……3秒……好吧,攒够了!

现哥用钱买了N块砖,标号1N,每块砖宽度和高度相同,但是长度不同,砖不能旋转。他想用这N块砖叠出一栋摩天大楼。不能有砖不用。为了摩天大楼不倒塌,现哥要求:除底层外,对于每一块砖,它的长度减去它下面的砖的长度必须小于等于D。但是现哥现在最感兴趣的是用这N块砖能搭出多少种不同的摩天大楼。两个摩天大楼不同,当且仅当两栋摩天大楼所用的N块砖从下到上的排列不相同。

 

【输入格式】

第一行两个数字ND

接下来N个数字,表示N块砖的长度。

 

【输出格式】

输出一个数,表示摩天大楼搭建的方案数mod 1000000007

 

【样例输入输出】

tall.in

tall.out

2 0

2 2

2

 

【样例解释】

由于2块砖的长度相同,所以他们可以任意排列,总共2种方案。

 

【数据范围】

30%的数据范围:1N10

100%的数据范围:1N2000000M109,砖长不超过109

【解题报告】

 1 #include <stdio.h>
 2 #include <cmath>
 3 #include <string.h>
 4 #include <algorithm>
 5 #define MAX 1000001
 6 #define MOD 1000000007
 7 using namespace std;
 8 int w[MAX],n,m,d,maxx=1;
 9 long long ans=1;
10 int main()
11 {
12     //freopen("tall.in","r",stdin);
13     //freopen("tall.out","w",stdout);
14     scanf("%d%d",&n,&d);
15     for(int i=1;i<=n;i++)
16         scanf("%d",&w[i]);
17     
18     sort(w+1,w+n+1);
19     
20     for(int i=2;i<=n;i++)
21     {
22         while(w[i]-d>w[maxx]&&maxx<i) maxx++; //max记录能放在上面最大的砖块
23         ans*=(i-maxx+1)*1LL;//乘法原理
24         ans%=MOD;
25     }
26     printf("%d\n",ans);
27     return 0;
28 }

 

posted @ 2017-02-06 15:50  yangyaojia  阅读(230)  评论(0编辑  收藏  举报