zoukankan      html  css  js  c++  java
  • CF1374E2 Solution

    题目链接

    题解

    (a_i,b_i)​4种情况的书分别存入4个优先队列。首先考虑满足(k)​,也就是在两人喜欢的书数目(le k)、所选书目(le m)​的条件下优先选择(a_i=b_i=1)的书,其次是将(a_i=0,b_i=1)(a_i=1,b_i=0)的两本书绑在一起选择。如果这样选择后喜欢书目仍(<k)​​,则判断无法满足。如果选择书目仍(le m),这时可以考虑由两本绑在一起的书替换一本(a_i=b_i=1)的书,或者新读一本当前时长最短的书,两者都可以使选择书目(+1)。每次从这两种方案中取最优,直到选够(m)本书即可。

    AC代码

    #include<bits/stdc++.h>
    #define mp make_pair
    #define pii pair<int,int>
    using namespace std;
    const int N=2e5+10,inf=0x3f3f3f3f;
    int t[N],a[N],b[N],n1,n2;
    priority_queue<pii ,vector<pii >,greater<pii> > q[5];
    pii ans[5][N];
    int main()
    {
    	int n,m,k,res=0;
    	scanf("%d%d%d",&n,&m,&k);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d%d%d",&t[i],&a[i],&b[i]);
    		if(a[i] && b[i]) q[0].push(mp(t[i],i));
    		if(!a[i] && b[i]) q[1].push(mp(t[i],i));
    		if(a[i] && !b[i]) q[2].push(mp(t[i],i));
    		if(!a[i] && !b[i]) q[3].push(mp(t[i],i));
    	}
    	while(m && k && !q[0].empty())
    	{
    		res+=q[0].top().first; 
    		ans[0][++n1]=q[0].top(); q[0].pop(); 
    		m--,k--;
    	}
    	while(m>1 && k && !q[1].empty() && !q[2].empty())
    	{
    		res+=q[1].top().first+q[2].top().first; 
    		ans[1][++n2]=q[1].top(),ans[1][++n2]=q[2].top(); 
    		q[1].pop(),q[2].pop();
    		m-=2,k--;
    	}
    	if(k) {printf("-1"); return 0;}
    	while(m--)
    	{
    		int minn=inf;
    		for(int i=0;i<=3;i++)
    			if(!q[i].empty()) minn=min(minn,q[i].top().first);
    		if(n1 && !q[1].empty() && !q[2].empty())
    		{
    			if(q[1].top().first+q[2].top().first-ans[0][n1].first<minn)
    			{
    				ans[1][++n2]=q[1].top(),ans[1][++n2]=q[2].top();
    				res+=q[1].top().first+q[2].top().first-ans[0][n1].first;
    				q[1].pop(),q[2].pop();
    				q[0].push(ans[0][n1]); n1--;
    				continue;
    			}
    		}
    		for(int i=0;i<=3;i++)
    		{
    			if(!q[i].empty() && minn==q[i].top().first)
    			{
    				ans[1][++n2]=q[i].top(),q[i].pop();
    				res+=minn; break;
    			}	
    		} 
    	}
    	printf("%d
    ",res);
    	for(int i=1;i<=n1;i++) printf("%d ",ans[0][i].second);
    	for(int i=1;i<=n2;i++) printf("%d ",ans[1][i].second);
    	return 0;
    }
    
  • 相关阅读:
    并查集
    关于一些位运算的小记
    用ST解决RMQ问题
    寒假作业_4
    H
    卢卡斯 组合数
    并查集
    G
    F
    E
  • 原文地址:https://www.cnblogs.com/violetholmes/p/15131808.html
Copyright © 2011-2022 走看看