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+优先队列)