2017 Multi-University Training Contest

来源:互联网 发布:windos无法连接到网络 编辑:程序博客网 时间:2024/05/18 19:47

http://acm.hdu.edu.cn/showproblem.php?pid=6047


题意:

先输入一个n表示数组a和数组b的元素个数,然后输入数组a,数组b,每次从数组b里挑1个(每个b里的元素只能用1次),现在要算an+1a2n,且满足an≤max{ajjbkj<i},使得an+1a2n的和最大。

思路:

用一个结构体把数组a的下标和对应的值存起来,然后用一个优先队列把数列a按照值从大到小排序。因为没有说数组b是按顺序的,所以要把数组b从小到大排个序,只要每次选择下标比b[i]大的数组a中最大的数,即能构成an+1~a2n的总和是最大的。

#include<bits/stdc++.h>using namespace std;#define ll long long#define MOD 1000000007#define MAXN 250050struct node{    ll val,idx;    bool operator < (const node &a) const {          return val < a.val;//最大值优先      }}temp;priority_queue<node> que;ll b[MAXN];bool cmp(ll a,ll b){    return a < b;}int main(){    ll n;    ll x;    while(~scanf("%lld",&n)){        ll ans = 0;        while(!que.empty()){            que.pop();        }        for(ll i = 1;i <= n;i++){            scanf("%lld",&x);            x = (x - i) % MOD;            que.push((node){x % MOD,i});        }        for(int i = 1;i <= n;i++){            scanf("%lld",&b[i]);        }        sort(b + 1,b + 1 + n,cmp);        for(int i = 1;i <= n;i++){            node flag = que.top();            while(flag.idx < b[i] && !que.empty()){//要下标比b[i]大的最大值                 que.pop();                flag = que.top();            }//            cout << flag.val << endl;            ans = (ans + flag.val) % MOD;            que.push((node){(flag.val - i - n) % MOD,i + n});        }        cout << ans << endl;    }}
原创粉丝点击