题意

你有 \(n\) 个任务,初始收益为 \(a\) ,共 \(t\) 轮游戏,每轮可以选择完成一个任务(可以做多次),完成之后可以给任意任务升级,升级之后的任务收益为 \(b\) ,每个任务还有完成的概率 \(p\) ,问期望最大收益是多少。

\(n\leq 10^5,1\leq a< b\leq 10^8,t\leq 10^9\)

分析

  • 一个重要而显然的结论是如果我们有了一次升级的机会,一定升级 \(b*p\) 最大的那一个,之后一直选择完成这个任务,记 \(M\) 表示最大的 \(b*p\) 。然后只关注没有一次完成时的最大期望收益。

  • 定义状态 \(f_t​\) 表示还剩 \(t​\) 轮游戏,还没有完成一个任务的期望最大收益。

  • 转移: \(f_{t+1}=\max\{p_i*(tM+a_i)+(1-p_i)*f_t\}\).

  • 可以变形成斜率优化的形式(注意这里的 \(f_t\) 要看成 \(k\) 的一部分) ,也可以写成这种形式:

\[f_{t+1}=\max\{p_i*(tM-f_t)+p_ia_i\}+f_t
\]

  • 将 \(p_i\) 看成 \(k\) , \(p_ia_i\) 看成 \(b\) ,然后每个转移都是形如直线 \(y=kx+b\) 的形式。

  • 我们可以维护一个下凸壳,每次可以二分当前的 \(x=tM-f_t\) 在哪一段,可以做到 \(Tlogn\) 的时间。

  • 发现 \(tM-f_t\)是单调不降的,证明如下:

设 \(x_{t+1} \geq x_t\)

有:\(tM-f_t\geq (t-1)M-f_{t-1}\)

\(M\geq f_t-f_{t-1}\)

考虑 \(f​\) 的实际意义可以发现上式一定成立,因为一轮的期望收益不会超过 \(M\) 。

可以考虑构造,对于 \(t+1\) 轮的最优决策, \(t\) 轮可以复制过来(除开第一轮),而在 \(t+1\) 轮产生的每种情况,\(t\) 轮都可以效仿(发生的概率是相同的),发现期望收益只有最后一轮不一样,最多差为 \(M\)。

  • 然后在每一段倍增矩乘即可。

  • 总时间复杂度为 \(O(n\log T)\)。

代码

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].lst,v=e[i].to)
  4. #define rep(i,a,b) for(int i=a;i<=b;++i)
  5. #define pb push_back
  6. typedef long long LL;
  7. inline int gi(){
  8. int x=0,f=1;char ch=getchar();
  9. while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
  10. while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
  11. return x*f;
  12. }
  13. template<typename T>inline bool Max(T &a,T b){return a<b?a=b,1:0;}
  14. template<typename T>inline bool Min(T &a,T b){return b<a?a=b,1:0;}
  15. const int N=1e5 + 7;
  16. typedef double db;
  17. const db eps=1e-12;
  18. int n,len,tp,st[N];
  19. LL t;
  20. db a[N],b[N],p[N],M;
  21. int dcmp(db x){
  22. if(fabs(x)<eps) return 0;
  23. return x<0?-1:1;
  24. }
  25. struct line{
  26. db k,b;int id;
  27. line(){}line(db k,db b,int id):k(k),b(b),id(id){}
  28. bool operator <(const line &rhs)const{
  29. if(dcmp(k-rhs.k)!=0) return dcmp(k-rhs.k)<0;
  30. return dcmp(b-rhs.b)<0;
  31. }
  32. }l[N];
  33. db X(int a,int b){
  34. return (l[b].b-l[a].b)/(l[a].k-l[b].k);
  35. }
  36. struct mat{
  37. db v[5][5];
  38. mat(){memset(v,0,sizeof v);}
  39. void init(){memset(v,0,sizeof v);}
  40. mat operator *(const mat &rhs)const{
  41. mat res;
  42. rep(i,0,4)
  43. rep(j,0,4)
  44. rep(k,0,4)
  45. res.v[i][j]+=v[i][k]*rhs.v[k][j];
  46. return res;
  47. }
  48. }A,B[34],C;
  49. mat Pow(mat a,LL b){
  50. mat res;
  51. rep(i,1,4) res.v[i][i]=1;
  52. for(;b;b>>=1,a=a*a) if(b&1) res=res*a;
  53. return res;
  54. }
  55. int main(){
  56. scanf("%d%I64d\n",&n,&t);
  57. rep(i,1,n) {
  58. scanf("%lf%lf%lf",&a[i],&b[i],&p[i]);
  59. l[i]=line(p[i],p[i]*a[i],i);
  60. Max(M,b[i]*p[i]);
  61. }
  62. sort(l+1,l+1+n);
  63. rep(i,1,n) {
  64. if(dcmp(l[i].k-l[i+1].k)==0) continue;
  65. l[++len]=l[i];
  66. }
  67. rep(i,1,len){
  68. while(tp>1&&dcmp(X(st[tp-1],i)-X(st[tp],st[tp-1]))<=0) --tp;
  69. st[++tp]=i;
  70. }
  71. int now=1;LL cnt=0;
  72. for(int now=1;now<=tp&&cnt^t;++now){
  73. double R=cnt*M-A.v[1][1];
  74. while(now<tp&&X(st[now],st[now+1])<=R) ++now;
  75. int i=st[now];R=X(st[now],st[now+1]);
  76. B[0].init();
  77. B[0].v[1][1]=1-l[i].k;
  78. B[0].v[2][1]=l[i].k;
  79. B[0].v[2][2]=B[0].v[3][1]=B[0].v[3][3]=B[0].v[4][2]=B[0].v[4][4]=1;
  80. A.v[1][3]=l[i].b,A.v[1][4]=M;
  81. rep(i,1,33) B[i]=B[i-1]*B[i-1];
  82. for(int i=33;~i;--i)if(t-cnt>(1ll<<i)){
  83. C=A*B[i];
  84. if(now==tp||dcmp((cnt+(1ll<<i))*M-C.v[1][1]-R)<0) A=C,cnt+=(1ll<<i);
  85. }
  86. cnt++,A=A*B[0];
  87. }
  88. printf("%.13lf\n",A.v[1][1]);
  89. return 0;
  90. }

[CF1067D]Computer Game[凸包/斜率优化+倍增+矩阵乘法]的更多相关文章

  1. CF1067D. Computer Game(斜率优化+倍增+矩阵乘法)

    题目链接 https://codeforces.com/contest/1067/problem/D 题解 首先,如果我们获得了一次升级机会,我们一定希望升级 \(b_i \times p_i\) 最 ...

  2. CF781D Axel and Marston in Bitland [倍增 矩阵乘法 bitset]

    Axel and Marston in Bitland 好开心第一次补$F$题虽然是$Div.2$ 题意: 一个有向图,每条边是$0$或$1$,要求按如下规则构造一个序列然后走: 第一个是$0$,每次 ...

  3. 【loj2325】「清华集训 2017」小Y和恐怖的奴隶主 概率dp+倍增+矩阵乘法

    题目描述 你有一个m点生命值的奴隶主,奴隶主受伤未死且当前随从数目不超过k则再召唤一个m点生命值的奴隶主. T次询问,每次询问如果如果对面下出一个n点攻击力的克苏恩,你的英雄期望会受到到多少伤害. 输 ...

  4. 倍增&矩阵乘法 专题复习

    倍增&矩阵乘法 专题复习 PreWords 这两个基础算法我就不多说啦,但是还是要介绍一下" 广义矩阵 "乘法 其实就是把矩阵换成取\(max\),然后都一样... 据神仙 ...

  5. BZOJ 3672[NOI2014]购票(树链剖分+线段树维护凸包+斜率优化) + BZOJ 2402 陶陶的难题II (树链剖分+线段树维护凸包+分数规划+斜率优化)

    前言 刚开始看着两道题感觉头皮发麻,后来看看题解,发现挺好理解,只是代码有点长. BZOJ 3672[NOI2014]购票 中文题面,题意略: BZOJ 3672[NOI2014]购票 设f(i)f( ...

  6. 4.28 省选模拟赛 负环 倍增 矩阵乘法 dp

    容易想到 这个环一定是简单环. 考虑如果是复杂环 那么显然对于其中的第一个简单环来说 要么其权值为负 如果为正没必要走一圈 走一部分即可. 对于前者 显然可以找到更小的 对于第二部分是递归定义的. 综 ...

  7. Codeforces 576D - Flights for Regular Customers(bitset 优化广义矩阵乘法)

    题面传送门 题意: 有一张 \(n\) 个点 \(m\) 条边的有向图,你初始在 \(1\) 号点,边上有边权 \(c_i\) 表示只有当你经过至少 \(c_i\) 条边的时候你才能经过第 \(i\) ...

  8. 【POJ3613】Cow Relays 离散化+倍增+矩阵乘法

    题目大意:给定一个 N 个顶点,M 条边的无向图,求从起点到终点恰好经过 K 个点的最短路. 题解:设 \(d[1][i][j]\) 表示恰好经过一条边 i,j 两点的最短路,那么有 \(d[r+m] ...

  9. dp斜率优化

    算法-dp斜率优化 前置知识: 凸包 斜率优化很玄学,凭空讲怎么也讲不好,所以放例题. [APIO2014]序列分割 [APIO2014]序列分割 给你一个长度为 \(n\) 的序列 \(a_1,a_ ...

随机推荐

  1. 【LLVM笔记】0x00 初识LLVM 链接类型

    模块结构 LLVM程序是由若干的模块(Module)组成,每个模块中包含有一些函数.全局变量和符号表. 这些模块可能由LLVM的连接器组合在一起,组合的过程将会整合这些函数和全局变量的定义,整合他们的 ...

  2. winform调用jar包

    因为工作需要,需要做一个数据上传的程序,客户规定的是:数据接口采用http连接,采用JSON-RPC轻量级远程调用协议.所以决定用winform做一个管理界面(其中还包括其他的功能),java完成数据 ...

  3. 通过ajax GET方式查询数据,Django序列化objects

    点击“查找2”按钮,通过ajax GET方式进行查询数据,这样页面不需要整体刷新,之后清空tbody数据,将查询结果重新附加到tbody 前端html: <div class="box ...

  4. Spark job 部署模式

    Spark job 的部署有两种模式,Client && Cluster spark-submit .. --deploy-mode client | cluster [上传 Jar ...

  5. 1)HDFS分布式文件系统 2)HDFS核心设计 3 )HDFS体系结构

    一.HDFS简介 1.HDFS:Hadoop distributed file system 一个分布式文件系统 基于流数据模式访问和处理超大文件的需要而开发 适合应用在大规模数据集上 2. 优点 处 ...

  6. NOIP2018考前抱佛脚——搜索复习

    目录 搜索 DFS 例1 P1101 单词方阵 题目描述 输入输出格式 输入输出样例 标程 例2 P1605 迷宫 题目背景 输入输出格式 输入输出样例 标程 例3 P1019 单词接龙 题目描述 输 ...

  7. 8.1Solr API使用(分页,高亮)

    转载请出自出处:http://www.cnblogs.com/hd3013779515/ 一.Solr Deep Paging(深分页) 长期以来,我们一直有一个深分页问题.如果直接跳到很靠后的页数, ...

  8. java多重转型问题

    我们来看一个简单的问题,下面的代码会打印出什么? public class hello { public static void main(String[] args){ System.out.pri ...

  9. bat替换文件的指定内容

    需求:替换文件my.ini中的1000 为10000,bat脚本如下: c:cd C:\Program Files\MySQL\MySQL Server 5.5copy my.ini my1126ba ...

  10. Redis系列五:redis键管理和redis数据库管理

    一.redis键管理 1 键重命名 rename oldKey newkey //格式rename oldKey newKey //若oldKey之前存在则被覆盖set name james :set ...