HDU4791【杂】
题意:
给你一个从0开始的区间si,每个区间是前闭后开,[ s[i] , s[i+1] ), 然后再给你个一个pi,代表你在区间[ s[i] , s[i+1] )里面买东西的单价是pi,给出的s1一定是0,给出的顺序是s1,p1,s2,p2...sk,pk,...sn,pn。然后给你个m个值,然后计算买了>=b[m]个物品需要花费的最少值;
思路:
预处理一下,买si个物品需要的花费,用个数组存一下从当前si量开始的最小花费,然后对于给入的值二分找一下他所在的区间[ s[i] , s[i+1] ),然后比较一下s[i+1]的最小和pi*给入的值的大小;注意是>=sn的时候;
贴一发比赛时的挫代码,一开始就瞎几把想其实预处理一下当前到最后的最小就行了。所以打的那么挫;
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N=1e5+10; int n; LL flag[N]; struct node { LL x; LL y; }; node qujian[N]; struct asd { LL page; LL w; }; asd q[N]; bool cmp1(node p1,node p2) { return p1.x<p2.x; } int main() { int n,m; int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) { scanf("%lld%lld",&qujian[i].x,&qujian[i].y); q[i].w=qujian[i].x*qujian[i].y; } sort(qujian+1,qujian+n+1,cmp1); LL temp=q[n].w; flag[n]=temp; for(int i=n-1; i>=1; i--) { if(temp>q[i].w) temp=q[i].w; flag[i]=temp; } // for(int i=1;i<=n;i++) // printf("%lld ",flag[i]); // puts(""); while(m--) { LL tmp; scanf("%lld",&tmp); int left=1; int right=n; while(left<right) { int mid=left+(right-left+1)/2; if(qujian[mid].x<=tmp) left=mid; //一定会变大 else right=mid-1; //一定会变小 } left++; // printf("%d\n",left); if(left>n) printf("%lld\n",qujian[left-1].y*tmp); else printf("%lld\n",(qujian[left-1].y*tmp)<flag[left]?(qujian[left-1].y*tmp):flag[left]); } } return 0; } /* 100 2 100 0 20 100 10 0 99 100 */