您的位置:首页 > 其它

[USACO Jan08] 化装晚会

2012-10-29 19:51 92 查看
万圣节又到了!Farmer John打算带他的奶牛去参加一个化装晚会,但是,FJ只做了一套能容 下两头总长不超过S(1 <= S <= 1,000,000)的牛的恐怖服装。FJ养了N(2 <= N <= 20,000)头按1..N顺序编号的奶牛,编号为i的奶牛的长度为L_i(1 <= L_i <= 1,000,000)。如果两头奶牛的总长度不超过S,那么她们就能穿下这套服装。

FJ想知道,如果他想选择两头不同的奶牛来穿这套衣服,一共有多少种满足条件的方案。

程序名: costume

输入格式:

第1行: 2个用空格隔开的整数:N 和 S

第2..N+1行: 第i+1为1个整数:L_i

输入样例 (costume.in):

4 6
3
5
2
1


输出格式:

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

输出样例 (costume.out):

4

输出说明:

4种选择分别为:奶牛1和奶牛3;奶牛1和奶牛4;奶牛2和奶牛4;奶牛3和奶牛4。

简单的单调队列。

#include<iostream>
#include<fstream>
using namespace std;
ifstream fin("costume.in");
ofstream fout("costume.out");

int n,s,h[20005],tot[20005]={0};

void Quick(int l,int r){
if(l>=r) return ;
int i=l,j=r,mid=h[(l+r)/2];
while(i<=j)
{
while(h[i]<mid) i++;
while(h[j]>mid) j--;
if(i<=j) {swap(h[i],h[j]);i++;j--;}
}
Quick(l,j);
Quick(i,r);
}

int main()
{
fin>>n>>s;

for(int i=1;i<=n;++i) fin>>h[i];

Quick(1,n);

int l=1,r=2;
while(h[l]+h[r]<=s&&r<=n) tot[l]++,r++;
r--;
l=2;
while(l<r&&r<=n)
{
tot[l]+=tot[l-1]-1;
while(h[l]+h[r]>s&&r>l) {tot[l]--;r--;}
l++;
}

int ans=0;
for(int i=1;i<=n;++i)
ans+=tot[i];

fout<<ans<<endl;

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: