HOJ12256临号不小于TDP

24 篇文章 0 订阅
//题目连接:http://acm.hnu.cn/online/?action=problem&type=show&id=12256&courseid=0
//题目大意:给定一个序列.问能够形成多少种序列,要求每个数-前一个数<=T
//解题思路:本题是一个DP题,自己考虑的时候就很多的去考虑前面的对后面的影响.
//考虑多了..反而弄得很复杂..如果按照DP的无后效性来考虑的话..会变得很简单的.
//举例一个序列 2 6 8 10 . t = 4 那么 考虑2的时候.能只有一个位置.S[1]=1
//然后6,能够放在二的前面.和最后一个位置(因为6是此时的最大值..并且不是2的后面.)
//那么s[2] = s[1]*2(因为6有两个可放的位置.)接下来是8.可以放在6的前面和最后
//一个位置.s[3]=s[2]*2,最后是10,可以放在6前面和8前面还有最后一个位置
//那么s[4]=s[3]*3.那么这样子做是不是一定正确.?有没有漏掉的或者是重复的呢?
//2和6 有2.6,6.2这两个序列.加入8..可以放在6前面和最后面..就是2.8.6,8.6.2
//2.6.8,6.2.8刚好符合..所以这样子的递推是正确的.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int mn = 11111111;
__int64 dp[mn];
int d[mn];
int binarysearch(int x,int n)
{
    int l = 1 , r = n;
    while(l <= r)
    {
        int mid = (l+r)/2;
        if(d[mid] == x && d[mid-1] == x)r = mid - 1;
        if(d[mid] < x)l = mid+1;
        else r = mid-1;
    }
    return l-1;
}
int main()
{
    int n,t;
    while(scanf("%d%d",&n,&t) != EOF)
    {
        for(int i = 1 ; i <= n ; i++)
          scanf("%d",&d[i]);
        for(int i = 0 ; i <= n ; i++)dp[i]=1;
        sort(d+1,d+n+1);
        for(int i = 1 ; i <= n ; i++)
        {
            int num = binarysearch(d[i]-t,i);
            num = i - num - 1;
            dp[i] = dp[i-1]*(num+1);
            dp[i] %=  1000000007;
            if(dp[i] < 0)while(1);
        }
        printf("%I64d\n",dp[n]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值