题目描述

有n个音符,第i个音符会在第i个时刻来临

令第 i 个音符的准备时间为 ti​ 个单位时间,如果选择去点击第 i 个音符,那么就没法点击所有到来时刻在 (iti​ ,i+ti​)中的音符。

每一个音符有一个权值,求一种点击方法使得权值和最高(N<=1e6)

Solution

首先先考虑最暴力的dp,令dp[i]表示我点到第i个时刻时,可以达到的最大权值

那么转移就很显然了

dp[i]=max(dp[j=1..i])+a[j](j+t[j]<=i&&i-t[i]>=j)

这个dp显然是O(n^2)的这时候我们发现每次循环1..i的过程十分的浪费时间所以我们来考虑优化这个过程

可以发现这是个二维偏序问题,一般的套路是一维排序另一维用数据结构去维护

因为i是递增的,这时候我们把所有的音符按照i+t[i]排序,并且用一个线段树维护区间内dp的最大值

为了满足j+t[j]<=i 我们在当前时刻>当前最小的i+t[i]的时候才把最小的i给modify进线段树里

每次查询的时候就只要查询1..i-t[i]的最大dp值然后只用最大dp值转移过来就可以了

这是一个O(N log N)的效率[因为评测姬跑的很快所以O(N log^2 N)跑过去了…]

Code

  1. //考场代码...结果脑子一抽考场上用了堆维护第一维关系... 所以这个代码效率是O(N log^2 N)  
  2. #include <bits/stdc++.h>  
  3. #define pa pair<long long,long long>  
  4. using namespace std;  
  5. inline long long read(){  
  6.    long long s=0,w=1;  
  7.    char ch=getchar();  
  8.    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}  
  9.    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();  
  10.    return s*w;  
  11. }  
  12. int N;  
  13. long long Tree[4005005];  
  14. void Change(int Now,int K,int l,int r,long long Ned)  
  15. {  
  16.     int mid=(l+r)/2;  
  17.     if (l==r&&l==K)  
  18.     {  
  19.       Tree[Now]=Ned;  
  20.       return;  
  21.     }  
  22.     if (K<=mid)  
  23.      Change(Now*2,K,l,mid,Ned);  
  24.     if (mid<K)  
  25.      Change(Now*2+1,K,mid+1,r,Ned);  
  26.     Tree[Now]=max(Tree[Now*2],Tree[Now*2+1]);  
  27. }  
  28. long long query(int Now,int L,int R,int l,int r)  
  29. {  
  30.     int mid=(l+r)/2;  
  31.     if (L<=l&&r<=R)  
  32.       return Tree[Now];  
  33.     long long qwqq=0;  
  34.     if (L<=mid)  
  35.     qwqq=max(query(Now*2,L,R,l,mid),qwqq);  
  36.     if (mid<R)  
  37.     qwqq=max(query(Now*2+1,L,R,mid+1,r),qwqq);  
  38.     return qwqq;  
  39. }  
  40. long long dp[1000005],a[1000005],t[1000005],Score[1000005];  
  41. priority_queue<pa,vector<pa>,greater<pa> > qwqq;  
  42. int main()  
  43. {  
  44.     freopen("fc.in","r",stdin);  
  45.     freopen("fc.out","w",stdout);  
  46.     N=read();  
  47.     for (int i=1;i<=N;i++)  
  48.       t[i]=read();  
  49.     for (int i=1;i<=N;i++)  
  50.       a[i]=read();  
  51.     for (int i=1;i<=N;i++)  
  52.       Score[i]=a[i]*t[i];  
  53.     for (int i=1;i<=N;i++)  
  54.     {  
  55.         pa r;  
  56.         if (!qwqq.empty()) r=qwqq.top();  
  57.         while (!qwqq.empty()&&r.first<=i)  
  58.          {  
  59.             Change(1,r.second,1,N,dp[r.second]);  
  60.             qwqq.pop();  
  61.             r=qwqq.top();  
  62.          }  
  63.         long long  R=0;  
  64.         if (i-t[i]>0)  
  65.         R=query(1,1,i-t[i],1,N);  
  66.         dp[i]=R+Score[i];  
  67.         pa Now;  
  68.         Now.first=i+t[i];  
  69.         Now.second=i;  
  70.         qwqq.push(Now);  
  71.     }  
  72.     long long ans=0;  
  73.     for (int i=1;i<=N;i++)  
  74.       ans=max(ans,dp[i]);  
  75.     printf("%lld",ans);  
  76.     return 0;  
  77. }  

FJWC2019 全连的更多相关文章

  1. fjwc2019 D1T1 全连(dp+树状数组)

    #178. 「2019冬令营提高组」全连 显然我们可以得出一个$O(n^2)$的dp方程 记$f(i)$为取到第$i$个音符时的最大分数,枚举下一个音符的位置$j$进行转移. 蓝后我们就可以用树状数组 ...

  2. fjwc2019

    机房搬迁.......再加上文化课.......咕了十几天才有空补上....... day0听一个教授讲理论......在学长的带领下咕掉了..... D1 T1:#178. 「2019冬令营提高组」 ...

  3. test20190320 全连(fc)

    题意 全连(fc) [题目背景] 还记得若干年前那段互相比较<克罗地亚狂想曲>的分数的日子吗? [题目描述] E.Space 喜欢打音游. 但是他技术不好,总是拿不到全连(Full Com ...

  4. SQL 表连接,内联、外联、全连

    内连接,join 或 inner join 两个表中符合条件的集合 外连接,left join  或  right  join 以left左边或right右边的表为数据集合行,根据条件,另一侧没有的数 ...

  5. fjwc2019 D6T1 堆(组合数+打表)

    #193. 「2019冬令营提高组」堆 但是每个点都遍历一遍,有些点的子树完全相同却重复算了 忽然记起完全二叉树的性质之一:每个非叶节点的子树中至少有一个是满二叉树 那么我们预处理满二叉树的那一块,剩 ...

  6. fjwc2019 D6T2 密文(trie+贪心)

    #194. 「2019冬令营提高组」密文 设$s[i]$表示前$i$个密文的异或和 容易发现,只要知道$s[0]~s[n](s[0]=0)$就可以知道每一位的值. 转化一下,就变成了在完全图上求最小生 ...

  7. fjwc2019 D4T1 循环流

    #187. 「2019冬令营提高组」循环流 假的网络流,其实是O(1)算法 手画n个图后,你会发现只要分成几种情况讨论讨论就得了. 当$a==1$时显然不存在. 当$a!=1$时 如果$n==2$,显 ...

  8. fjwc2019 D3T2 送分题

    #185. 「2019冬令营提高组」送分题 这是原题..... P3615 如厕计划 手推一推你发现,显然男性不能多于女性. 然后你或许可以发现一个神奇的性质. 对于每个序列,我们记$M$为$1$,$ ...

  9. fjwc2019 D3T1 签到题 (贪心)

    #184. 「2019冬令营提高组」签到题 每次询问接近O(1).......考虑贪心 怎么贪心呢? 对于相邻的两个数,我们要保证异或x后单调不降 我们找到两个数二进制上最高的相异位 当左边的数相异位 ...

随机推荐

  1. 安装系统重启的时候出现了error:file '/boot/grub/i386-pc/normal.mod' not found

    1.直接进入系统的时候只出现grub rescue的命令行 可以使用的命令有set和 ls 在用ls命令查看 磁盘的分区情况其中hd0 代表第一块硬盘 hd1代表第二块 使用ls 来查看存在那些系统, ...

  2. 一起学Angular

    最近想做一款跨平台(pc\app\pad)的东西玩玩,研究了许多技术: android.ios.H5.Bootrap.angular.angular2.ApiCloud.微信小程序 除android. ...

  3. 整理用js实现tab标签页

    首先是css样式,比如这样的: <style> *{ ; ; list-style: none; font-size: 12px; } .notice{ width: 298px; hei ...

  4. selenium设置代理,基于chrome浏览器

    工作中遇到需要对项目中使用的selenium设置代理,跟大家分享一下. 1.下载chromeDriver:http://chromedriver.storage.googleapis.com/inde ...

  5. Android-XML与JSON的理解-JSON的数据格式

    据我了解,在多年以前浏览器客户端和服务器它们的通讯数据交互格式是XML, 使用XML来规定数据格式可读性确实非常强,XML的魅力确实很大,也很成熟,但是也有不足之处,就是在网络传输的时候对流量要求特别 ...

  6. Centos 下安装tomcat多实例

    基础环境及JDK就不多说了,下面的目录结构以如下为准: 根目录-apps根目录-apps--tomcat根目录-apps--ins1根目录-apps--ins2 =================== ...

  7. sql2008 获取表结构说明

    SELECT     表名       = case when a.colorder=1 then d.name else '' end,    表说明     = case when a.color ...

  8. LINQ to Entities 查询中的标准查询运算符

    投影和筛选方法 投影指的是转换的结果集到所需的窗体中的元素. 例如,可以从结果集中的每个对象投影所需的属性子集,可以投影一个属性并对其执行数学计算,也可以从结果集投影整个对象. 投影方法有 Selec ...

  9. zTree设置选中节点之后出现重复节点

    1.用户离开页面时最后一次点击的节点信息我会保存到数据库. 2.用户打开页面时默认选中上一次离开时选中的节点. 现在发现在设置选中节点之后,会出现重复的节点(重复现象偶尔出现). 以下是代码: var ...

  10. 数据库表结构文档查看器 基于netcore

    前言 日常开发业务代码,新接手一块不熟悉的业务时需要频繁的查看对应业务的数据库表设计文档.相比于直接翻看业务代码,有必要提供一个数据库表结构文档查看器来解决这些繁琐的问题. CML.SqlDoc CM ...