hdu 6047 Maximum Sequence 贪心
Description
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<i}, and any bkbk can’t be chosen more than once. Apparently, there are a great many possibilities, so you are required to find max{∑2nn+1ai∑n+12nai} modulo 109109+7 .
Now Steph finds it too hard to solve the problem, please help him.
Input
For each test case, the first line consists of one integer n. The next line consists of n integers representing {ai}. And the third line consists of n integers representing {bi}.
1≤n≤250000, n≤a_i≤1500000, 1≤b_i≤n.
Output
Sample Input Sample Output
数列要满足aj <= max{ai - i},其中bk <= j < i,bk是数列b中的一项,且每个bk最多仅能取一次
看到这里肯定还看不明白。
具体说一下第一个样例:
a数组是8 11 8 5 b数组是3 1 4 2
现在要扩充a数组,然后数组的扩充方法是,a数组中每个数等于本身减去他的下标,然后从b数组中选一个数,然后a数组的这个数的位置开始到最后选一个最大的(只能解释到这样了)。
实现:a数组相当于 (8-1)(11-2)(8-3)(5-4)
从b数组中选择1,代表从a[1]到a[4]中选择一个最大的,选择9。然后将9添加到a数组中,然后数组为(8-1)(11-2)(8-3)(5-4) (9-5)
然后第二次从b数组中选择2代表从a[2]到a[5]中选择一个最大的,选择9。然后将9添加到a数组中,然后数组为(8-1)(11-2)(8-3)(5-4) (9-5)(9-6)
然后第三次从b数组中选择3代表从a[3]到a[6]中选择一个最大的,选择5。然后将5添加到a数组中,然后数组为(8-1)(11-2)(8-3)(5-4) (9-5)(9-6)(5-7)
然后第四次从b数组中选择4代表从a[4]到a[7]中选择一个最大的,选择4。然后将9添加到a数组中,然后数组为(8-1)(11-2)(8-3)(5-4) (9-5)(9-6)(5-7)(4-8)
然后更新完成了。最后数列a的n+1到2*n项的值为9+9+5+4=27
思路:
要想使数列a的n+1到2*a项最大,又每项都要减去i
所以应该尽量使bk最小,从最前面开始(可以理解为贪心)
那么肯定要先把最大的放进来
将b排序,计算ai - i的值
开一个max数组记录从i 到最后一项的最大ai-i的值(可以从后往前找)
每次加入点的时候,从后往前比较,如果小于这个数,就更新为这个数。
用一个sum记录总和。
记得每次加的结果要%mod。
注意数组要开为数据量的两倍,因为a数组要扩展!
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
int mod=1e9+;
using namespace std;
int a[],b[],maxx[];
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(maxx,,sizeof(maxx));
for(int i=; i<=n; i++)
{
scanf("%d",a+i);
a[i]-=i;
}
for(int i=; i<=n; i++)
{
scanf("%d",b+i);
}
sort(b+,b+n+);
maxx[n]=a[n];
for(int i=n; i>=; i--)//更新max数组
{
maxx[i-]=max(a[i-],maxx[i]);
}
int flag=n+;
int sum=;
for(int i=; i<=n; i++)
{
sum+=maxx[b[i]];//选择最大的数
a[flag]=maxx[b[i]]-(flag);
maxx[flag]=a[flag];
for(int j=flag-; j>=; j--)//加入新的点之后,要更新对应的max
{
if(maxx[j]<maxx[flag])
maxx[j]=maxx[flag];
else break;
}
flag++;
sum=sum%mod;
}
printf("%d\n",sum);
}
}
最新文章
- javascript如何设置DIV背景色为随机色
- 犀利的background-clip:text,实现K歌字幕效果
- ubuntu server下建立分区表/分区/格式化/自动挂载(转)
- maven中文乱码问题——编译错误
- OO之美2
- C#索引器的作用及使用
- 【http】client
- java中a++与++a区别
- js广告图片轮播
- SimpleMembership
- linux批量压缩当前目录中文件后,删除原文件
- springAOP实现操作日志记录,并记录请求参数与编辑前后字段的具体改变
- fastjson 操作
- java实现pdf按页切分成图片
- sqlserver float小数存数据库变成多位了 比如说12.23存进去变成 12.229999998 甚至更长
- Nutch源码阅读进程4
- 虚拟机中多个Linux系统之间配置免秘钥访问
- Git Hooks、GitLab CI持续集成以及使用Jenkins实现自动化任务
- 一道SQL题
- Linux 常用环境搭建
热门文章
- hihocoder1445 后缀自动机二&#183;重复旋律5
- Spring理论基础-控制反转和依赖注入
- 大聊Python----SocketServer
- bzoj 2434 fail tree+dfs序
- bzoj 2321 数学
- adb操作指令大全
- Android 聊天软件客户端
- 【DeepLearning学习笔记】Coursera课程《Neural Networks and Deep Learning》——Week2 Neural Networks Basics课堂笔记
- 细数雷军系成员,27家公司3家IPO
- 浅析linux内核中timer定时器的生成和sofirq软中断调用流程【转】