bzoj 2013 上升计数

 

题意: 给一个数集和一个数d,问满足下列要求的排列数(相同的数要区分):  a[i]+d>=a[i+1] ( i in [1,n) )

 

因为数的给出顺序不重要,所以先排序,假如我们已经解决了前i个数的答案,考虑前i+1个数,即我们可以将第i+1个数放在哪,然后发现对于前i个数的每一种方案,我们都可以选择将第i+1个数放在大于等于它-d的数的上面,从而形成一种新的方案(当然直接可以放在地上),然后就完了.

收获:

  1. 对于不重要的东西(如原序列的顺序),可以直接舍弃

  2. 减小问题规模,发现小规模的问题和比它大一数据规模的问题之间的联系.

 

 1 /**************************************************************
 2     Problem: 2013
 3     User: idy002
 4     Language: C++
 5     Result: Accepted
 6     Time:988 ms
 7     Memory:10492 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <algorithm>
12 #define N 620010
13 #define Mod 1000000009
14 using namespace std;
15  
16 typedef long long dnt;
17  
18 int n;
19 dnt h[N], d;
20 dnt dp[N];
21  
22 int main() {
23     scanf( "%d%lld", &n, &d );
24     for( int i=1; i<=n; i++ )
25         scanf( "%lld", h+i );
26     sort( h+1, h+1+n );
27     dnt cur = 1;
28     for( int i=1; i<=n; i++ ) {
29         int j = lower_bound( h+1, h+i, h[i]-d ) - h;
30         cur = cur*(i-j+1) % Mod;
31     }
32     printf( "%lld\n", cur );
33 }
34 
View Code

 

posted @ 2015-06-15 16:25  idy002  阅读(227)  评论(0编辑  收藏  举报