题意:
有i种物品,每种物品需要买k[i]个,然后商店会有m次特价出售,第j次为在di天出售第ti种物品,物品原价2元,特价1元,你每天上午可以获得一元,下午可以进行交易,求获取所有物品花费的最少时间为多少天?
思路:
如果第i天满足条件,则i+1天一定满足,所有二分答案.
如何判断答案x是否符合:
按贪心策略去判断:可以在该物品特售的最后一天将目前的全部钱去购买,没有特价买到的可以第x天花原价买。
代码:
#include<bits/stdc++.h> #define ll long long using namespace std; const ll inf=1e12; const int N=200005; ll K[N], n, m, k[N]; struct trade { ll d, t; }w[N]; bool cmp(struct trade a,struct trade b) { return a.d<b.d; } bool check(ll x) { for(int i=1; i<=n; i++) { k[i]=K[i]; } ll t=x, p=0, ti=x; for(int i=m-1; i>=0; i--) { if(w[i].d>x) { continue; } ti=min(w[i].d,ti); if(ti>=k[w[i].t]) { ti=ti-k[w[i].t]; t=t-k[w[i].t]; k[w[i].t]=0; } else { t=t-ti; k[w[i].t]-=ti; ti=0; break; } } ll sum=0; for(int i=1; i<=n; i++) { sum=sum+k[i]; } if(sum*2>t) { return 0; } return 1; } int main() { scanf("%lld%lld",&n,&m); for(int i=1; i<=n; i++) { scanf("%lld",&K[i]); } for(int i=0; i<m; i++) { scanf("%lld%lld",&w[i].d,&w[i].t); } sort(w,w+m,cmp); ll l=0, r=inf; while(r-l>1) { ll mid=(l+r)/2; if(check(mid)) { r=mid; } else { l=mid; } } cout << r << endl; return 0; }