题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4791
题目意思:打印资料,给定N个不同的 si 表示分区间计费,打印处于si 和 si+1 的区间时,收费pi 元 给定 m个询问,让你求出每次打印最省钱的方案。
分析:题目意思不难理解,很容易想到用二分,找出处于哪个区间,然后比较这个值跟后面所有 si 的端点的花费最小的。 不过这样子每次去搜索可能会超时间,所有我们可以预处理一下数据。从后往前 遍历一边,把 si 后的最优条件 存储下来。
比赛的时候,一直过不了这个题目,找不出来哪里错了。就是过不了,想了好多数据验算都没问题。赛后才知道,这个题目不用能lld输出,而要用I64输出
<pre name="code" class="cpp">
#include <stdio.h>
#include <iostream>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <bitset>
#include <queue>
using namespace std;
typedef long long ll;
ll p[100083],s[100083],n;
ll v[100083];
int binary(int L,int R,int key)
{
int ret;
while(L<=R)
{
int mid=(L+R)/2;
if(key>=s[mid])
{
L=mid+1;
ret=mid; <span style="font-family: Arial, Helvetica, sans-serif;">//二分查找出 处于哪两个区间,这里找出的是下界。</span>
}
else
R=mid -1;
}
return ret;
}
int main()
{
int T;
cin>>T;
while(T--)
{
int n, m;
cin >>n>>m;
for(int i=0;i<n;i++)
{
scanf("%I64d%I64d",&s[i],&p[i]);
}
v[n-1]=s[n-1]*p[n-1];
for(int i=n-1;i>=1;i-- ) <span style="font-family: Arial, Helvetica, sans-serif;">//这里是对预处理后面找出最优条件的数组。</span>
{
v[i-1]=min(v[i],s[i-1]*p[i-1]);
}
ll g, result, k;
for(int i=0;i<m;i++)
{
scanf("%I64d",&g);
k=binary(0,n-1,g);
if(k==n-1)
result=g*p[n-1];
else
{
result=min(g*p[k],v[k+1]);
}
printf("%I64d\n",result);
}
}
return 0;
}