HDU - 6047 多校2 1003 Maximum Sequence (贪心+优先队列)

Steph is extremely obsessed with “sequence problems” that are usually seen on magazines: Given the sequence 11, 23, 30, 35, what is the next number? Steph always finds them too easy for such a genius like himself until one day Klay comes up with a problem and ask him about it.

Given two integer sequences {ai} and {bi} with the same length n, you are to find the next n numbers of {ai}: an+1…a2nan+1…a2n. Just like always, there are some restrictions on an+1…a2nan+1…a2n: for each number aiai, you must choose a number bkbk from {bi}, and it must satisfy aiai≤max{ajaj-j│bkbk≤j

题意

给出长度为n的两个数组a,b
其中1<=bi<=n
每次从b中取一个数(不重复取同一个数)
然后在 a数组中 将第j个数 设置为 a[bi]-bi~a[n+j-1]-(n+j-1) 中的最大值。
求,最大的sigm(a[n+1]~a[n+n]).

思路

应该有更简单的思路
我当时想的是
1.贪心:先把将b排序,然后从小到大取b中的数
因为肯定要越大的数尽量放在前面才可以保证 再后面安排的数会可能取到更大
2.然后就是一个优先队列,将(a[i]-i,i) push进去,大的a[i]-i 在前面。每次取b[i]的时候,判断一下下标,如果b[i]小于等于队首值的下标那么说明可以取到队首这个最大值;否则说明当前这个队首值取不到了,就需要将队首值弹出去,直到找到一个队首值的下标大于b[i] 说明可以取。每次取完需要把新的(a[i+n]-(i+n),i+n)push进去 ,因为可能后加进去的值会成为最大值。

注意

ans要开longlong 这个是肯定的
bug:最开始push(Pair(a[i]-i,i))push错了
写成了(a[i]-i,b[i])…….手残
嗯。。答案还要取余 不要忘了

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const long long MOD=1e9+7;
int a[250005],b[250005];
struct Pair{
    int id;
    long long v;
    Pair(long long V,int ID){
        v=V;
        id=ID;
    }
    friend bool operator <(const Pair a,const Pair b){
        if(a.v!=b.v) return a.v<b.v;
        else return a.id>b.id;
    }
};

priority_queue<Pair> que;

int main() {
    freopen("1003.in","r",stdin);
//  freopen("1003.txt","w",stdout);
    int n;
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<=n;i++) scanf("%d",&b[i]);
        sort(b+1,b+1+n);
        while(!que.empty()) que.pop();
        long long ans=0;
        for(int i=1;i<=n;i++){
            que.push(Pair((long long )a[i]-i,i));
        }
        for(int i=1;i<=n;i++){
            struct Pair f=que.top();
            if(b[i]>f.id){
                while(1){
                    que.pop();
                    f= que.top();
                    if(f.id>=b[i])break;
                }
            }
            ans= (ans+f.v) % MOD;
//          cout<<f.v<<"**"<<endl;
            que.push(Pair(f.v-(n+i),n+i));
        }
        printf("%lld\n",ans);
    }

}
/*
9
0 1
1 0
1 2
2 -1
2 1
2 3
3 2
4 1
3 0
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值