HDU6047 Maximum Sequence(贪心,2017 HDU多校联赛 第2场)

来源:互联网 发布:java读取身份证阅读器 编辑:程序博客网 时间:2024/06/05 19:44

题目;
Maximum Sequence

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 57 Accepted Submission(s): 25

Problem Description
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…a2n. Just like always, there are some restrictions on an+1…a2n: for each number ai, you must choose a number bk from {bi}, and it must satisfy ai≤max{aj-j│bk≤j

思路:

题意是给了一个a数组,长度是n,然后要求从a[n+1]~a[2*n]的和

它的计算方法是这样的;
从a[n+1]开始,a[j]的值等于你在b数组中选一个数字k,那么a[j]的值就是a[j]-j(j<k<i)的最大值

以第一个样例来说明

编号 1 2 3 4 a 8 11 8 5 b 3 1 4 2

我们第一次从b数组选出来的数字是2,那么
从a[2]开始算起
a[2]-2=9
a[3]-3=5
a[4]-4=1
a[5]的值就是他们中间最大的,也就是a[5]=9

到了计算a[6]的情况,这次我们在b数组里面选择1
a[1]-1=7
a[2]-2=9
a[3]-3=5
a[4]-4=1
a[5]-5=4

所以a[6]的值是9,以此类推
a[7]=5,a[8]=4

他们的和=9+9+5+4=27

我们的做法是直接在a[i]中存储a[i]-i的值,然后定义数组ma[i],代表以i为起点,到后面区间所能得到最大值

然后后开一个优先队列,让值比较大的先出队,把b数组中的每一个ma[b[i]]值都放到优先队列中,每次取队首,那么队首就是我们所要求的那个最大值,用tmp来存储n+1以后a[i]-i的最大值,每次更新a[i],最后取模就是答案,具体看代码

代码

#include <cstdio>#include <cstring>#include <cctype>#include <string>#include <set>#include <iostream>#include <stack>#include <cmath>#include <queue>#include <vector>#include <algorithm>#define mem(a,b) memset(a,b,sizeof(a))#define inf 0x3f3f3f3f#define N 250010#define ll long longusing namespace std;const int mod=1e9+7;int a[N*2],b[N],ma[N];int main(){  int n;  while(~scanf("%d",&n))  {      mem(ma,0);mem(a,0);      int x;      for(int i=1; i<=n; i++)      {          scanf("%d",&x);          a[i]=x-i;      }      for(int i=n; i>=1; i--)          ma[i]=max(a[i],ma[i+1]);//计算从i为开始,所能达到的最大值      for(int i=1; i<=n; i++)          scanf("%d",&b[i]);      priority_queue<int>q;      for(int i=1; i<=n; i++)          q.push(ma[b[i]]);      int ans=0,tmp=0;      for(int i=n+1; i<=2*n; i++)      {          int s=q.top();          if(tmp>s)              a[i]=tmp-i;          else          {              a[i]=s-i;              q.pop();          }          ans=(ans+a[i]+i)%mod;          tmp=max(tmp,a[i]);      }      printf("%d\n",ans%mod);  }  return 0;}
阅读全文
0 0
原创粉丝点击