1 条题解

  • 0
    @ 2026-9-23 22:46:14

    反悔贪心模板题。

    维护一个按任务用时排序的大根堆,保存当前选中的任务。

    将任务按照发布期限排序,若当前状态下该任务可以完成,则钦定任务完成,并扔进堆中;否则取出堆顶,若当前任务用时比堆顶短,则弹出堆顶,将该任务塞进去。容易证明这是优的。

    题目要求打印方案,于是在循环结束后,取出堆中所有元素,即为选中的任务。

    Code:

    /*
    
      2025.6.26
    
     * Happy Zenith noise *
    
    */
    #include<bits/stdc++.h>
    #define int long long
    #define fi first
    #define se second
    #define pb push_back
    using namespace std;
    typedef pair<int,int>P;
    const int MAXN=1000005;
    struct node{
    	int w,t,id;
    }a[MAXN],b[MAXN];
    int n,s,ans;
    priority_queue<P>q;
    bool cmp(node x,node y){return x.t<y.t;}
    signed main(){
    	cin>>n;
    	for(int i=1;i<=n;i++)cin>>a[i].w>>a[i].t,a[i].id=i;
    	sort(a+1,a+1+n,cmp);
    	for(int i=1;i<=n;i++){
    		if(s+a[i].w<=a[i].t){
    			s+=a[i].w;ans++;
    			q.push({a[i].w,i});
    		}
    		else if(!q.empty()){
    			P tmp=q.top();
    			if(tmp.fi>a[i].w)q.pop(),s=s-tmp.fi+a[i].w,q.push({a[i].w,i});
    		}
    	}	
    	cout<<ans<<"\n";s=1,ans=0;
    	while(!q.empty())b[++ans]=a[q.top().se],q.pop();
    	sort(b+1,b+1+ans,cmp);
    	for(int i=1;i<=ans;i++)cout<<b[i].id<<" "<<s<<"\n",s+=b[i].w;
        return 0;
    }
    
    • 1

    [POI 2021/2022 R1] 剪辑师 / Montażysta

    信息

    ID
    3418
    时间
    4000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者