题意:给你2n个数,b[i]表示不小于a[i]页数时的单价,问你印刷一定页数时,最便宜是多少钱。因为可以选择再刷多n页来改变单价从而改变总价格,所以要考虑的东西比较多。下面给代码。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<string>
#include<queue>
#include<cmath>
#include<set>
using namespace std;
#define maxn 100005
#define xx 1000000001
int a[maxn], b[maxn], n, m;
int binarysearch(int value)
{
int left = 1, right = n, mid;
while (left<right)
{
mid = (left + right) >> 1;
if (value>a[mid])left = mid + 1;
else right = mid - 1;
}
if (a[left]<=value)return left;
return left - 1;
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d%d", &a[i], &b[i]);
}
for (int i = n - 1; i >= 1; i--) {
if ((long long)a[i] * b[i]>(long long)a[i + 1] * b[i + 1]) {
a[i] = a[i + 1];
b[i] = b[i + 1];
}
}//因为后面的价格有可能会更便宜,所以进行以上操作
a[0] = xx;
b[0] = xx;
a[n + 1] = xx;
b[n + 1] = xx;
for (int i = 0; i < m; i++) {
int q;
scanf("%d", &q);
int index = binarysearch(q);//暴力明显会超时,套二分就可以了。
long long x = min((long long)b[index] * q, (long long)b[index + 1] * a[index + 1]);
printf("%lld\n", x);
}
}
}