题意:
商店一共有n种商品 每种商品有a[i]个 这些商品如果是在售 则需要一金币 否则需要二金币
求最少天数买完商店所有的商品 每天早上会得到1金币
然后给出m条在售信息: day ,t (代表第几天 第i钟商品在售)
显然用二分答案来做
judge的时候应该先维护每种商品优惠的最后一天!(这样才是最优的) 然后再遍历一遍 在每种商品的最后一天进行贪心
#include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m) #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s); #define ll long long #define pb push_back #define REP(i,N) for(int i=0;i<(N);i++) #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// #define inf 0x3f3f3f3f const int N=2e5+5; int a[N]; struct node { int day,t; }s[N]; bool cmp(node a,node b){return a.day<b.day;} int n,m,sum; int vis[N];int last[N]; bool judge(int x) { memcpy(vis,a,sizeof a); int cnt=0; int money=0; CLR(last,0); rep(i,1,m) if(x>=s[i].day) last[s[i].t]=max(last[s[i].t],s[i].day); rep(i,1,m) if(x>=s[i].day) { money+=s[i].day-s[i-1].day; if(s[i].day==last[s[i].t]) { int temp=min(money,vis[s[i].t]); cnt+=temp; vis[s[i].t]-=temp; money-=temp; } } return sum-cnt<=x; } int main() { RII(n,m); rep(i,1,n) RI(a[i]),sum+=a[i]; sum*=2; rep(i,1,m) RII(s[i].day,s[i].t); sort(s+1,s+1+m,cmp); int L=1,R=sum; int ans=0; while(L<=R){int m=(L+R)>>1; if(judge(m))R=m-1,ans=m; else L=m+1; } cout<<ans; return 0; }