现哥的摩天大厦 乘法原理
本文为博主原创文章,如转载,请标明出处www.cnblogs.com/yangyaojia
现哥的摩天大厦(tall.pas/c/cpp)
Time Limit:1s Memory Limit:256MB
【题目描述】
现哥准备从现在从没钱开始攒钱建座摩天大厦!1秒……2秒……3秒……好吧,攒够了!
现哥用钱买了N块砖,标号1到N,每块砖宽度和高度相同,但是长度不同,砖不能旋转。他想用这N块砖叠出一栋摩天大楼。不能有砖不用。为了摩天大楼不倒塌,现哥要求:除底层外,对于每一块砖,它的长度减去它下面的砖的长度必须小于等于D。但是现哥现在最感兴趣的是用这N块砖能搭出多少种不同的摩天大楼。两个摩天大楼不同,当且仅当两栋摩天大楼所用的N块砖从下到上的排列不相同。
【输入格式】
第一行两个数字N,D。
接下来N个数字,表示N块砖的长度。
【输出格式】
输出一个数,表示摩天大楼搭建的方案数mod 1000000007。
【样例输入输出】
tall.in |
tall.out |
2 0 2 2 |
2 |
【样例解释】
由于2块砖的长度相同,所以他们可以任意排列,总共2种方案。
【数据范围】
30%的数据范围:1≤N≤10。
100%的数据范围:1≤N≤200000。0≤M≤109,砖长不超过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 }