The Strongest Build(a,b,有序数列的和维护第k大的思想)

Posted thusloop

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了The Strongest Build(a,b,有序数列的和维护第k大的思想)相关的知识,希望对你有一定的参考价值。

The Strongest Build
题意 :给了n组有序数组 ,每个数组中取一个数使得和最大的取法 ,(取法不能为被禁用的取法 )
思路:a,b,有序数列求和 取第k大的思想,先把a,b中最大的放入优先队列(大根堆) ,a[n-1]+b[n],a[n]+b[n-1]放入优先队列(下标不越界的情况下) ,并且每个取法只能放入一次优先队列,执行到k次的时候就是答案了 。
这题就是用这个思想维护一下最大值,当最大值能取的时候直接输出。

#include<bits/stdc++.h>
#define int long long
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int inf=2e18+100;
const int maxn=2e5+100;
vector<int>g[15];
vector<int>v,now;
map<vector<int>,bool>mp,use;
int pos[15];
priority_queue<pair<int,vector<int>>>q;
signed main()
{
	IOS
	int n;
	cin>>n;
	int sum=0;
	for(int i=1; i<=n; i++)
	{
		int x;
		cin>>x;
		for(int j=1; j<=x; j++)
		{
			int tp;
			cin>>tp;
			g[i].push_back(tp);
		}
		pos[i]=x-1;
		sum+=g[i][x-1];
	}
	for(int i=1; i<=n; i++)
	{
		now.push_back(pos[i]);
	}
	q.push({sum,now});
	int m;
	cin>>m;
	for(int i=1; i<=m; i++)
	{
		int tp;
		v.clear();
		for(int j=1; j<=n; j++)
		{
			cin>>tp;
			v.push_back(tp-1);
		}
		mp[v]=1;
	}
	use[now]=1;
	while(!q.empty())
	{
		auto tp=q.top();
		q.pop();
		now=tp.second;
		if(mp[now]==0)
		{
			for(auto it:now)
			{
				cout<<it+1<<" ";
			}
			cout<<"\\n";
			return 0;
		}
		v=now;
		sum=tp.first;
		int sum2=sum;
		for(int i=0; i<n; i++)
		{
			if(v[i]>0)
			{
				sum2-=g[i+1][v[i]];
				v[i]--;
				sum2+=g[i+1][v[i]];
				if(use[v]==0)
				{
					use[v]=1;
					q.push({sum2,v});
				}
				v[i]++;
				sum2=sum;
			}
		}
	}
}

以上是关于The Strongest Build(a,b,有序数列的和维护第k大的思想)的主要内容,如果未能解决你的问题,请参考以下文章

D. The Strongest Build(bfs+优先队列)

D. The Strongest Build(bfs+优先队列)

D. The Strongest Build(bfs+优先队列)

D. The Strongest Build二叉堆,map乱搞

B-Build the Permutation

多个 LIKE 运算符 ORDER BY Strongest