[BZOJ1572] WorkScheduling
本题可以采用贪心
算法一:按工作时间排序,如果工作能按时完成的工作就按时完成,如果工作不能按时完成就把之前价值最小的工作和当前作比较,取最优的情况。考虑使用堆维护工作价值。
算法二:按工作价值排序,因为所有工作花费的是一样的,价值大的尽量完成,考虑把工作拖到最后完成。每个工作从完成期限往前找,找到第一个空的时段,用这个时间完成工作。考虑用并查集快速查找空的时段。如果该工作完成时间>n,则一定可以完成,并查集只要维护<=n的部分。
1 #include <cstdio> 2 #include <queue> 3 #include <algorithm> 4 #define LL long long 5 struct Work{int d,p;}W[100005]; 6 std::priority_queue<LL,std::vector<LL>,std::greater<LL> >Q; 7 bool cmp(Work A,Work B){return A.d<B.d; } 8 int main(){ 9 //freopen("in.txt","r",stdin); 10 //freopen("out.txt","w",stdout); 11 int n,size=0;LL ans=0; 12 scanf("%d",&n); 13 for(int i=1;i<=n;++i) 14 scanf("%d %d",&W[i].d,&W[i].p); 15 std::sort(W+1,W+n+1,cmp); 16 for(int i=1;i<=n;++i) 17 if(size<W[i].d){ 18 ans=ans+W[i].p; 19 ++size; 20 Q.push(W[i].p); 21 }else if(Q.top()<W[i].p){ 22 ans=ans-Q.top()+W[i].p; 23 Q.pop(); 24 Q.push(W[i].p); 25 } 26 printf("%lld",ans); 27 //fclose(stdin);fclose(stdout); 28 return 0; 29 }
#include <cstdio> #include <algorithm> #define LL long long int Pre[100005]; struct Work{int d,p;}W[100005]; bool cmp(Work A,Work B){return A.p>B.p;} int GetPre(int x){return Pre[x]==x?x:Pre[x]=GetPre(Pre[x]);} int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n;LL ans=0; scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d %d",&W[i].d,&W[i].p); std::sort(W+1,W+n+1,cmp); for(int i=1;i<=n;++i)Pre[i]=i; for(int i=1,pre;i<=n;++i) if(W[i].d>n){ ans=ans+W[i].p; }else{ pre=GetPre(W[i].d); if(!pre)continue; ans=ans+W[i].p; Pre[pre]=pre-1; } printf("%lld",ans); //fclose(stdin);fclose(stdout); return 0; }