Description

N soldiers from the famous "*FFF* army" is standing in a line, from left to right.

  1. o o o o o o o o o o o o o o o o o o /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \

You, as the captain of *FFF*, want to divide them into smaller groups, but each group should still be continous in the original line. Like this:

  1. o o o | o o o o | o o o o o o | o o o o o /F\ /F\ /F\ | /F\ /F\ /F\ /F\ | /F\ /F\ /F\ /F\ /F\ /F\ | /F\ /F\ /F\ /F\ /F\ / \ / \ / \ | / \ / \ / \ / \ | / \ / \ / \ / \ / \ / \ | / \ / \ / \ / \ / \

In your opinion, the number of soldiers in each group should be no more than L.  Meanwhile, you want your division be "holy". Since the soldier may have different heights, you decide that for each group except the first one, its last soldier(which is the rightmost one) should be strictly taller than the previous group's last soldier. That is, if we set bi as the height of the last soldier in group i. Then for i >= 2, there should be b i > b i-1.  You give your division a score, which is calculated as , b 0 = 0 and 1 <= k <= M, if there are M groups in total. Note that M can equal to 1.  Given the heights of all soldiers, please tell us the best score you can get, or declare the division as impossible.

 

Input

The first line has a number T (T <= 10) , indicating the number of test cases.  For each test case, first line has two numbers N and L (1 <= L <= N <= 10 5), as described above.  Then comes a single line with N numbers, from H1 to Hn, they are the height of each soldier in the line, from left to right. (1 <= H i <= 10 5)
 

Output

For test case X, output "Case #X: " first, then output the best score.

题目大意:有n个数,划分为多个部分,假设M份,每份不能多于L个。每个数有一个h[i],每份最右边的那个数要大于前一份最右边的那个数。设每份最右边的数为b[i],求最大的sum{b[i]² - b[i - 1]},1≤i≤M,其中b[0] = 0。

思路:朴素DP为,dp[i]表示以i为结尾的最大划分。那么dp[i] = max{dp[j] - h[j] + h[i]²},1≤i-j≤L,h[j]<h[i]。这种会超时,采取线段树优化。因为有两个限制,考虑到若h[j]≥h[i],那么求i的时候一定不会用到j,那么先按h排序再DP(h相同的,i大的排前面)。

PS:又忘了把int改成long long >_<

代码(781MS):

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstring>
  4. #include <algorithm>
  5. using namespace std;
  6. typedef long long LL;
  7.  
  8. const int MAXN = ;
  9.  
  10. LL dp[MAXN];
  11. int n, L;
  12. LL tree[MAXN << ], maxt[MAXN << ];
  13.  
  14. void pushdown(int x) {
  15. int ll = x << , rr = ll ^ ;
  16. if(tree[x] != -) {
  17. tree[ll] = max(tree[x], tree[ll]);
  18. tree[rr] = max(tree[x], tree[rr]);
  19. maxt[ll] = max(maxt[ll], tree[x]);
  20. maxt[rr] = max(maxt[rr], tree[x]);
  21. tree[x] = -;
  22. }
  23. }
  24.  
  25. void update(int x, int left, int right, int a, int b, LL val) {
  26. if(a <= left && right <= b) {
  27. tree[x] = max(tree[x], val);
  28. maxt[x] = max(maxt[x], val);
  29. }
  30. else {
  31. pushdown(x);
  32. int ll = x << , rr = ll ^ ;
  33. int mid = (left + right) >> ;
  34. if(a <= mid) update(ll, left, mid, a, b, val);
  35. if(mid < b) update(rr, mid + , right, a, b, val);
  36. maxt[x] = max(maxt[x], max(maxt[ll], maxt[rr]));
  37. }
  38. }
  39.  
  40. LL query(int x, int left, int right, int a, int b) {
  41. if(a <= left && right <= b) return maxt[x];
  42. else {
  43. pushdown(x);
  44. int ll = x << , rr = ll ^ ;
  45. int mid = (left + right) >> ;
  46. LL ret = -;
  47. if(a <= mid) ret = max(ret, query(ll, left, mid, a, b));
  48. if(mid < b) ret = max(ret, query(rr, mid + , right, a, b));
  49. return ret;
  50. }
  51. }
  52.  
  53. struct Node {
  54. int h, pos;
  55. void read(int i) {
  56. pos = i;
  57. scanf("%d", &h);
  58. }
  59. bool operator < (const Node &rhs) const {
  60. if(h != rhs.h) return h < rhs.h;
  61. return pos > rhs.pos;
  62. }
  63. } a[MAXN];
  64.  
  65. LL solve() {
  66. sort(a + , a + n + );
  67. dp[n] = -;
  68. memset(tree, , sizeof(tree));
  69. memset(maxt, , sizeof(maxt));
  70. update(, , n, , , );
  71. for(int i = ; i <= n; ++i) {
  72. LL tmp = query(, , n, max(, a[i].pos - L), a[i].pos - );
  73. if(tmp == -) {
  74. if(a[i].pos == n) break;
  75. else continue;
  76. }
  77. dp[a[i].pos] = tmp + LL(a[i].h) * a[i].h;
  78. if(a[i].pos == n) break;
  79. update(, , n, a[i].pos, a[i].pos, dp[a[i].pos] - a[i].h);
  80. }
  81. //for(int i = 1; i <= n; ++i) printf("%I64d\n", dp[i]);
  82. return dp[n];
  83. }
  84.  
  85. int main() {
  86. int T; scanf("%d", &T);
  87. for(int t = ; t <= T; ++t) {
  88. scanf("%d%d", &n, &L);
  89. for(int i = ; i <= n; ++i) a[i].read(i);
  90. LL ans = solve();
  91. if(ans == -) printf("Case #%d: No solution\n", t);
  92. else printf("Case #%d: %I64d\n", t, ans);
  93. }
  94. }

HDU 4719 Oh My Holy FFF(DP+线段树)(2013 ACM/ICPC Asia Regional Online ―― Warmup2)的更多相关文章

  1. HDU 4722 Good Numbers(位数DP)(2013 ACM/ICPC Asia Regional Online ―― Warmup2)

    Description If we sum up every digit of a number and the result can be exactly divided by 10, we say ...

  2. HDU 4717 The Moving Points(三分法)(2013 ACM/ICPC Asia Regional Online ―― Warmup2)

    Description There are N points in total. Every point moves in certain direction and certain speed. W ...

  3. HDU 4714 Tree2cycle(树状DP)(2013 ACM/ICPC Asia Regional Online ―― Warmup)

    Description A tree with N nodes and N-1 edges is given. To connect or disconnect one edge, we need 1 ...

  4. HDU 4725 The Shortest Path in Nya Graph(最短路径)(2013 ACM/ICPC Asia Regional Online ―― Warmup2)

    Description This is a very easy problem, your task is just calculate el camino mas corto en un grafi ...

  5. HDU 5889 Barricade 【BFS+最小割 网络流】(2016 ACM/ICPC Asia Regional Qingdao Online)

    Barricade Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...

  6. HDU4719-Oh My Holy FFF(DP线段树优化)

    Oh My Holy FFF Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) T ...

  7. HDU 4747 Mex(线段树)(2013 ACM/ICPC Asia Regional Hangzhou Online)

    Problem Description Mex is a function on a set of integers, which is universally used for impartial ...

  8. hdu 4747 Mex (2013 ACM/ICPC Asia Regional Hangzhou Online)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4747 思路: 比赛打得太菜了,不想写....线段树莽一下 实现代码: #include<iost ...

  9. HDU 4729 An Easy Problem for Elfness(主席树)(2013 ACM/ICPC Asia Regional Chengdu Online)

    Problem Description Pfctgeorge is totally a tall rich and handsome guy. He plans to build a huge wat ...

随机推荐

  1. 初学oracle遇到些小麻烦

    前段时间学习了Oracle数据库,在超级用户sys下运行一些基本语句的时候都没有发现有什么问题,但是却发现不能执行删除字段的的命令,老师检查说可能是权限不够,但是在授权之后依旧不能完成该语句,所以就另 ...

  2. Python语法糖

    1.装饰器 ####装饰器的固定格式 ##普通版本 def timer(func): def inner(*args,**kwargs): '''执行函数之前要做的''' ret = func(*ar ...

  3. Navicat for Mysql中错误提示索引过长1071-max key length is 767 byte

    1.建用户信息表 tb_person_info create table tb_person_info( user_id int(10) auto_increment, `name` varchar( ...

  4. Reverse a String-freecodecamp算法题目

    Reverse a String(翻转字符串) 题目要求: 把字符串转化成数组 借助数组的reverse方法翻转数组顺序 把数组转化成字符串 思路: 用.split('')将字符串转换成单个字母组成的 ...

  5. (暴力碾标算)NOIP模拟赛 宗教仪式

    题意: 一个模式串,一个文本串,现定义最大失配值为k 求文本中最大失配值<=k的长度为len(模式串)的字串个数 失配值=当前字串中与模式串不同的字符个数 思路: 暴力,加一个跳出剪枝,居然过了 ...

  6. boost::asio::ip::tcp中几个重要类型

    typedef basic_stream_socket socket; 流式套接字,提供同/异步发送接收数据,连接,绑定,设置套接字选项等功能 对于socket中的connect()方法,它只针对某一 ...

  7. win10家庭版升级为win10专业版

    windows10 升级钥匙: DR9VN-GF3CR-RCWT2-H7TR8-82QGT 亲测可用

  8. [转]App离线本地存储方案

    App离线本地存储方案 原文地址:http://ask.dcloud.net.cn/article/166 HTML5+的离线本地存储有如下多种方案:HTML5标准方案:cookie.localsto ...

  9. vi-vim常用命令

    vi-vim常用命令 1 简介 在UNIX系统中,创建和修改配置文件.shell脚本.初始化文件.编写程序都离不开VI. 1      vi[1]属于两个主要的UNIX规范:POSIX和单一UNIX规 ...

  10. python3 练习题100例 (二十二)输入两个字符串,输出两个字符串集合的并集

    题目内容: 输入两个字符串,输出两个字符串集合的并集. 为保证输出结果一致,请将集合内元素排序之后再输出, 如对于集合aset,可输出sorted(aset). 输入格式: 共两行,每一行为一个字符串 ...