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()
{IOSint 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;}}}
}