cqyz oj | 化装晚会 | 二分搜索 | 贪心

Description

  万圣节又到了!FJ打算带他的奶牛去参加一个化装晚会,但是FJ只做了一套能容下两头总长不超过 S 的牛的恐怖服装。FJ养了 N 头按 1..N 顺序编号的奶牛,编号为 i 的奶牛的长度为 Li。如果两头奶牛的总长度不超过 S,那么她们就能穿下这套服装。
  FJ想知道,如果他想选择两头不同的奶牛来穿这套衣服,一共有多少种满足条件的方案。

Input

  第 1 行是 2 个用空格隔开的整数 N 和 S;  接下来有 n 行,每行包含一个整数 L_i,表示奶牛的身长为。

Output

  仅一行一个整数,表示FJ可选择的所有方案数。注意奶牛顺序不同的两种方案是被视为相同的

Sample Input 1

4 6
3 5 2 1

Sample Output 1

4

Hint

2 <= N <= 1,000,0001 <= S <= 2,000,000,0001 <= L_i <= 2,000,000,000


首先可以注意到数据量很大,所以先放弃\(O(n^2)\)的暴力枚举法。

首先想到可以排序后对每头牛i二分搜索和它满足条件的第二头牛j,,则比j长度小的牛也都满足条件,枚举第一头牛+二分搜索,复杂度\(O(nlogn)\)

如果从大向小枚举i,那么其实没必要每次重新二分找j,因为满足前一头牛的j一定满足当前的牛(想一想,为什么)。所以j可以按从小到大的顺序移动。复杂度降为\(O(n)\)
细节见代码:

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <iomanip>
#define inf 0x7f7f7f7f
using namespace std;
int n,s,cow[1000005];
long long ans=0;
int readd(int &x) //快读int 
{
    char ch;
    x=0;
    while(!isdigit(ch)) ch=getchar();
    while(isdigit(ch))
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return 0;
}
int main()
{
    scanf("%d%d",&n,&s);
    for(int i=1;i<=n;i++) readd(cow[i]);
    sort(cow+1,cow+1+n);
    int i=1,j=n;
    for(j=n;j>=1;j--)
    {
        while(i<=n && cow[j]+cow[i]<=s) i++;
        if(j>=i)ans+=i-1;
        else    ans+=i-2;
    }
    cout<<ans/2;
}

转载于:https://www.cnblogs.com/de-compass/p/11252901.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值