您的位置:首页 > 大数据 > 人工智能

2017 Multi-University Training Contest - Team 2 1003 【贪心 + 优先队列】

2017-07-27 23:02 459 查看
传送门

//题意还是稍微有点难懂, 就是在序列a后面再添n个元素, 但是每一个元素要满足题目所给的条件, 就是从b序列中任意抽出一个, 使得a序列中从b[k]下标到即将被添加的那个元素的下标中抽取一个max, 最后求出a(n+1)~a(n+n)的和mod, 注意每一个b[k]最多只能被用一次, 而且注意每一个b[i]的范围都是<=n的.

//思路: 为了max, 所以贪心的选择, 每一次我们都选可以选到的最大值, 并且新加进去的元素也可以使用, 所以我用的是一个优先队列去维护一个最大的val值.

//ps:mmp, 比赛的时候吧数据范围看错, 写的1e5, 一直T, T到想吐血. 后面才发现范围开小了, 开成5e5就过了…….

AC Code (483ms)

/** @Cain*/
#define Fill(x,y) memset(x,y,sizeof(x))
using namespace std;
const int maxn=5e5+5;
int a[maxn],b[maxn];
struct node
{
int id,val;
bool friend operator<(const node &x,const node &y){
return x.val<y.val;
}
node(int id=0,int val = 0):id(id),val(val){}
};

void solve()
{
int n;
while(~scanf("%d",&n)){
priority_queue<node>q;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
q.push(node(i,a[i]-i));
}
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
sort(b+1,b+n+1);
ll res = 0; int r = 1;
int cnt = 1;
while(!q.empty()){
node t = q.top();
q.pop();
for(int i=r;i<=n;i++){
if(b[i]<=t.id){
r = i+1;
res += t.val;
res %= mod;
q.push(node(n+cnt,t.val-n-cnt));
cnt++;
}
else break;
}
if(cnt > n) break;
}
printf("%lld\n",res);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐