题意:有m个鬼会来拜访你,每个鬼拜访你的时间wi给出,每次拜访都是1s,你有一些蜡烛,你要保证每次鬼拜访你的时候都有最少r根蜡烛亮着才不会害怕,每根蜡烛燃烧的时间是t,点燃一根蜡烛花费1s时间,也就是在x时间点蜡烛,x+1到x+1+t是亮的,现在求最少花费多少蜡烛,如果不能使每个鬼拜访你的时候都有r个蜡烛亮着输出-1
思路:树状数组+扫描线,每次判断当前时间是否有r个蜡烛亮着,如果不够就往前加,尽量在靠后的时间点蜡烛,有一点注意,最多同时使t个蜡烛保持亮的状态
AC代码:
#include "iostream" #include "string.h" #include "stack" #include "queue" #include "string" #include "vector" #include "set" #include "map" #include "algorithm" #include "stdio.h" #include "math.h" #pragma comment(linker, "/STACK:102400000,102400000") #define ll long long #define endl (" ") #define bug(x) cout<<x<<" "<<"UUUUU"<<endl; #define mem(a,x) memset(a,x,sizeof(a)) #define mp(x,y) make_pair(x,y) #define pb(x) push_back(x) #define ft (frist) #define sd (second) #define lrt (rt<<1) #define rrt (rt<<1|1) using namespace std; const long long INF = 1e18+1LL; const int inf = 1e9+1e8; const double eps=1e-4; const int N=6e4+100; const ll mod=1e9+7; int m,t,r,ans,w[305]; int C[615]; int lowbit(int x){ return (-x)&x; } int sum(int x){ int ret=0; while(x>0){ ret+=C[x]; x-=lowbit(x); } return ret; } void add(int x, int z){ while(x<=610){ C[x]+=z; x+=lowbit(x); } } int main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); cin>>m>>t>>r; if(r>t){ cout<<-1; return 0; } for(int i=1; i<=m; ++i){ cin>>w[i];//cout<<sum(w[i]+300)<<endl; if(sum(w[i]+305)<r){ int c=r-sum(w[i]+305); ans+=c; for(int ti=w[i]-c; ti<w[i]; ++ti){ //cout<<ti+300+1<<" "<<ti+t+1+300<<endl; add(ti+305,1), add(ti+t+1+305,-1); } } } cout<<ans<<endl; return 0; }