题意:
给你一个长度为n的数组v,你需要把这个数组分成很多段,你需要保证每一段的长度不能超过k
我们设一共有m段,每一段右边界那个数为bi
那么我们要使得sum(bi*bi-b(i-1))最大 (1<=i<=m,b0=0)
你需要保证bi>b(i-1) (1<=i<=m)
sum():表示求和

题解:
我们设数组下标从1开始
dp[i]表示:对于v数组的前i个数的最大sum(bi*bi-b(i-1))为dp[i]
dp转移方程:
dp[i]=dp[j]+v[i]*v[i]-v[j] (i>j且v[i]>v[j])
dp转移方程很容易找到,但是如果对于一个i,我们去寻找所有满足条件的j的话就该TLE了

那么我们可以使用线段树进行维护,维护第i个位置的值为dp[i]-v[i]。这样的话对于一个j(j>i)
我们只需要在线段树的[1,j-1]区间查找出来最大的值就可以了
对于查找出来的值我们只需要加上v[j]*v[j]就是dp[j]的值(这一点很重要,可以说就是把维护的值改变了一下)

但是我们发现题目还要求v[j]>v[i],怎么办呢,我们可以对所有vi排序,按照排过序之后顺序进行线段树维护查找更新
就可以了



  1. 代码:
  1. /*
  2. 题意:
  3. 给你一个长度为n的数组v,你需要把这个数组分成很多段,你需要保证每一段的长度不能超过k
  4. 我们设一共有m段,每一段右边界那个数为bi
  5. 那么我们要使得sum(bi*bi-b(i-1))最大 (1<=i<=m,b0=0)
  6. 你需要保证bi>b(i-1) (1<=i<=m)
  7. sum():表示求和
  8.  
  9. 题解:
  10. 我们设数组下标从1开始
  11. dp[i]表示:对于v数组的前i个数的最大sum(bi*bi-b(i-1))为dp[i]
  12. dp转移方程:
  13. dp[i]=dp[j]+v[i]*v[i]-v[j] (i>j且v[i]>v[j])
  14. dp转移方程很容易找到,但是如果对于一个i,我们去寻找所有满足条件的j的话就该TLE了
  15.  
  16. 那么我们可以使用线段树进行维护,维护第i个位置的值为dp[i]-v[i]。这样的话对于一个j(j>i)
  17. 我们只需要在线段树的[1,j-1]区间查找出来最大的值就可以了
  18. 对于查找出来的值我们只需要加上v[j]*v[j]就是dp[j]的值(这一点很重要,可以说就是把维护的值改变了一下)
  19.  
  20. 但是我们发现题目还要求v[j]>v[i],怎么办呢,我们可以对所有vi排序,按照排过序之后顺序进行线段树维护查找更新
  21. 就可以了
  22. */
  23.  
  24. #include <iostream>
  25. #include <cstdio>
  26. #include <cstring>
  27. #include <cstdlib>
  28. #include <algorithm>
  29. using namespace std;
  30. typedef long long ll;
  31. const int maxn=1e5+10;
  32. const int mod=20071027;
  33. const int INF=0x3f3f3f3f;
  34. ll tree[maxn<<2],dp[maxn];
  35. ll max(ll a,ll b)
  36. {
  37. if(a<b) return b;
  38. else return a;
  39. }
  40. void push_up(ll rt)
  41. {
  42. tree[rt]=max(tree[rt<<1],tree[rt<<1|1]);
  43. }
  44. void update(ll rt,ll L,ll R,ll pos,ll val)
  45. {
  46. if(L==R)
  47. {
  48. tree[rt]=val;
  49. return;
  50. }
  51. ll mid=(L+R)>>1;
  52. if(pos<=mid) update(rt<<1,L,mid,pos,val);
  53. else update(rt<<1|1,mid+1,R,pos,val);
  54. push_up(rt);
  55. }
  56. ll query(ll rt,ll L,ll R,ll LL,ll RR)
  57. {
  58. if(LL<=L && RR>=R)
  59. {
  60. return tree[rt];
  61. }
  62. ll mid=(L+R)>>1,ans=-1;
  63. if(LL<=mid) ans=max(ans,query(rt<<1,L,mid,LL,RR));
  64. if(RR>mid) ans=max(ans,query(rt<<1|1,mid+1,R,LL,RR));
  65. return ans;
  66. }
  67. struct shudui
  68. {
  69. ll val,id;
  70. }v[maxn],w[maxn];
  71. bool cmp(shudui x,shudui y)
  72. {
  73. return x.val<y.val;
  74. }
  75. int main()
  76. {
  77. ll t,p=0;
  78. scanf("%lld",&t);
  79. while(t--)
  80. {
  81. ll pos=0;
  82. memset(tree,-1,sizeof(tree));
  83. memset(dp,-1,sizeof(dp));
  84. ll n,k;
  85. scanf("%lld%lld",&n,&k);
  86. if(k==1)
  87. {
  88. for(ll i=1;i<=n;++i)
  89. scanf("%lld",&v[i].val),v[i].id=i;
  90. ll res=v[1].val*v[1].val,flag=0;
  91. for(ll i=2;i<=n;++i)
  92. {
  93. if(v[i].val>v[i-1].val)
  94. {
  95. res=(res+v[i].val*v[i].val)-v[i-1].val;
  96. }
  97. else
  98. {
  99. flag=1;
  100. break;
  101. }
  102. }
  103. if(flag==0)
  104. printf("Case #%lld: %lld\n",++p,res);
  105. else printf("Case #%lld: No solution\n",++p);
  106. continue;
  107. }
  108. for(ll i=2;i<=n+1;++i)
  109. scanf("%lld",&v[i].val),v[i].id=i;
  110. update(1,1,n,1,0);
  111. dp[1]=v[1].val*v[1].val;
  112. ll tmp=dp[1]-v[1].val;
  113. sort(v+2,v+2+n,cmp);
  114. //printf("%lld**************\n",query(1,1,n,3,4));
  115. for(ll i=2;i<=n+1;++i)
  116. {
  117. if(pos>0 && v[i].val!=v[i-1].val)
  118. {
  119. //printf("%lld*******\n",pos);
  120. for(ll i=0;i<pos;++i)
  121. {
  122. update(1,1,n,w[i].id,w[i].val);
  123. }
  124. pos=0;
  125. }
  126. if(v[i].id==1)
  127. {
  128. w[0].id=1;
  129. w[0].val=tmp;
  130. pos++;
  131. continue;
  132. }
  133. ll ans=query(1,1,n,max(1,v[i].id-k),v[i].id-1);
  134. //printf("%lld %lld*****\n",ans,v[i].id);
  135. if(ans!=-1)
  136. {
  137. w[pos].id=v[i].id;
  138. w[pos].val=(ans+v[i].val*v[i].val)-v[i].val;
  139. dp[v[i].id]=max(w[pos].val+v[i].val,dp[v[i].id]);
  140. pos++;
  141. }
  142. }
  143. if(dp[n+1]!=-1)
  144. printf("Case #%lld: %lld\n",++p,dp[n+1]);
  145. else printf("Case #%lld: No solution\n",++p);
  146. }
  147. return 0;
  148. }

hdu4719 Oh My Holy FFF 线段树维护dp的更多相关文章

  1. hdu4719 Oh My Holy FFF 线段树优化dp

    思路 好久之前的了,忘记什么题目了 可以到我这里做luogu 反正就是hdu数据太水,导致自己造的数据都过不去,而hdu却A了 好像是维护了最大值和次大值,然后出错的几率就小了很多也许是自己写错了,忘 ...

  2. Codeforces Round #271 (Div. 2) E题 Pillars(线段树维护DP)

    题目地址:http://codeforces.com/contest/474/problem/E 第一次遇到这样的用线段树来维护DP的题目.ASC中也遇到过,当时也非常自然的想到了线段树维护DP,可是 ...

  3. codeforces Good bye 2016 E 线段树维护dp区间合并

    codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...

  4. Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake 线段树维护dp

    D. Babaei and Birthday Cake 题目连接: http://www.codeforces.com/contest/629/problem/D Description As you ...

  5. Codeforces GYM 100114 D. Selection 线段树维护DP

    D. Selection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descriptio ...

  6. 【BZOJ2164】采矿 树链剖分+线段树维护DP

    [BZOJ2164]采矿 Description 浩浩荡荡的cg大军发现了一座矿产资源极其丰富的城市,他们打算在这座城市实施新的采矿战略.这个城市可以看成一棵有n个节点的有根树,我们把每个节点用1到n ...

  7. 【8.26校内测试】【重构树求直径】【BFS模拟】【线段树维护DP】

    题目性质比较显然,相同颜色联通块可以合并成一个点,重新建树后,发现相邻两个点的颜色一定是不一样的. 然后发现,对于一条链来说,每次把一个点反色,实际上使点数少了2个.如下图 而如果一条链上面有分支,也 ...

  8. 2019牛客暑期多校训练营(第二场)E 线段树维护dp转移矩阵

    题意 给一个\(n\times m\)的01矩阵,1代表有墙,否则没有,每一步可以从\(b[i][j]\)走到\(b[i+1][j]\),\(b[i][j-1]\),\(b[i][j+1]\),有两种 ...

  9. Codeforces750E. New Year and Old Subsequence (线段树维护DP)

    题意:长为2e5的数字串 每次询问一个区间 求删掉最少几个字符使得区间有2017子序列 没有2016子序列 不合法输出-1 题解:dp i,p(0-4)表示第i个数匹配到2017的p位置删掉的最少数 ...

随机推荐

  1. 浅谈JVM垃圾回收

    JVM内存区域 要想搞懂啊垃圾回收机制,首先就要知道垃圾回收主要回收的是哪些数据,这些数据主要在哪一块区域. Java8和Java8之前的相同点有很多. 都有虚拟机栈,本地方法栈,程序计数器,这三个是 ...

  2. Linux 安装JDK配置环境(rpm安装和压缩版安装)

    jdk安装 (rpm安装) jdk下载地址: https://www.oracle.com/cn/java/technologies/javase/javase-jdk8-downloads.html ...

  3. 【Nginx】配置nginx图片服务器

    想通过nginx来访问服务器上的图片 可以搭建一个nginx图片服务器. 做法如下: 先安装nginx,这里直接用yum来进行安装的 安装方法如下: https://blog.csdn.net/iml ...

  4. 【Linux】rsync模板配置问题

    ------------------------------------------------------------------------------------------------- | ...

  5. 【Linux】saltstack 安装及简单使用

    准备三台server,一台为master(10.96.20.113),另两台为minion(10.96.20.117,10.96.20.118) 主机名(master.minion1.minion2) ...

  6. LeetCode501.二叉搜索树中的众数

    题目,本题未做出,还有很多要学习 class Solution { public: vector<int>ans; int base,count,maxCount; void update ...

  7. 【葵花宝典】一天掌握Docker

    第1章Docker 概述 1-1 Docker是什么 没有虚拟化技术的原始年代 我们仔细想想,在没有计算虚拟化技术的"远古"年代,如果我们要部署一个应用程序(Application ...

  8. 转 Jmeter测试实践:文件上传接口

    Jmeter测试实践:文件上传接口   1.打开jmeter4.0,新建测试计划,添加线程组.根据实际情况配置线程属性. 2.添加HTTP请求. Basic部分修改如下: Advanced部分我做任何 ...

  9. Linux更换软件源

    1. Ubuntu16.04 sudo cp /etc/apt/sources.list /etc/apt/sources_origin.list # 备份 sudo gedit /etc/apt/s ...

  10. 三. SpringCloud服务注册与发现

    1. Eureka 1.1 Eureka理解 什么是服务治理 Spring Cloud封装了Netflix公司开发的Eurkeka模块来实现服务治理 在传统的rpc远程调用框架中,管理每个服务与服务之 ...