codeJan喜欢观察世界。有一天,codeJan发现一个非常奇怪的现象。有一些年轻的青蛙聚集在一条直线上的某些位置上,同一个位置可能有多个青蛙。这些青蛙每次只会向前跳一米,并且每只青蛙每跳一次都会发出’WA’的一声。codeJan想在一些青蛙的位置上放置黑洞来收集全部的青蛙。在黑洞位置上的青蛙会直接掉进黑洞中不会发出任何叫声,其余的青蛙经过若干次跳跃都会掉进在它前面的最近的黑洞。因为WA类似WrongAnswer,所以codeJan想要知道他合理地安排黑洞的位置,最少可以听到多少声WA?在听到最少声WA时,需要准备的每个黑洞的容量至少为多少?黑洞的容量体现为可以容纳的青蛙的最大数量,所有黑洞的容量应该都相同。

输入描述:

  1. 第一行一个正整数T20表示测试组数。每组测试样例的第一行是两个正整数n,m,分别表示存在青蛙的位置和可以放置黑洞的数量。接下来n行,每行包含两个正整数a[i],b[i]分别表示第i组青蛙的位置(单位:米)和这个位置上青蛙的数量。

输出描述:

  1. 对于每组测试用例用一行输出两个正整数分别表示最少可以听到多少声WA和黑洞的最少容量。用空格隔开,行末无空格。
示例1

输入

  1. 2
  2. 3 1
  3. 1 1
  4. 2 2
  5. 3 3
  6. 3 2
  7. 1 1
  8. 4 2
  9. 2 3

输出

  1. 8 6
  2. 3 4

说明

  1. 对于第一个样例,只能放在 1 位置,因此听到的 WA 的次数为:1*0+2*1+3*2=8,所有青蛙汇聚在一次,容量至少为 6
    对于第二个样例,可以放在 1 4 位置,因此听到的 WA 的次数为:1*0+3*1+2*0=31 位置和 2 位置的青蛙汇聚在一 起,需要容量为 44 位置的青蛙单独在一起,需要容量为 2。因此容量至少为 4

备注:

  1. 输入保证a[i] a[j](i j),1mn1001a[i],b[i]≤106

题解

$dp$,二分。

$dp[i][j]$表示到$i$位置,分了$j$段的最小花费,每一个区间的花费可以预处理。

$dp[1][m]$就是第一个答案。

对于第二个答案,容量越大,最小花费肯定越小,容量越小,最小花费越大,利用这个单调性就可以二分,假设二分到的容量为$x$,那么$dp$的时候外加一个条件控制一下区间和要小于等于$x$。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. const int maxn = 100 + 10;
  5. int T, n, m;
  6. struct X {
  7. int a, b;
  8. }s[maxn];
  9. long long cost[maxn][maxn];
  10. long long dp[maxn][maxn];
  11. long long sum[maxn][maxn];
  12. long long limit;
  13.  
  14. bool cmp(const X& a, const X& b) {
  15. return a.a < b.a;
  16. }
  17.  
  18. int check(long long mid) {
  19. for(int i = 1; i <= n; i ++) {
  20. dp[i][1] = 1e18;
  21. if(sum[i][n] <= mid) dp[i][1] = cost[i][n];
  22. }
  23. for(int j = 2; j <= m; j ++) {
  24. for(int i = n - j + 1; i >= 1; i --) {
  25. dp[i][j] = 1e18;
  26. for(int k = i + 1; k <= n; k ++) {
  27. if(dp[k][j - 1] != 1e18 && sum[i][k - 1] <= mid) {
  28. dp[i][j] = min(dp[i][j], dp[k][j - 1] + cost[i][k - 1]);
  29. }
  30. }
  31. }
  32. }
  33. if(limit == dp[1][m]) return 1;
  34. return 0;
  35. }
  36.  
  37. int main() {
  38. scanf("%d", &T);
  39. while(T --) {
  40. scanf("%d%d", &n, &m);
  41. for(int i = 1; i <= n; i ++) {
  42. scanf("%d%d", &s[i].a, &s[i].b);
  43. }
  44. sort(s + 1, s + 1 + n, cmp);
  45. for(int i = 1; i <= n; i ++) {
  46. for(int j = i; j <= n; j ++) {
  47. cost[i][j] = cost[i][j - 1] + 1LL * (s[j].a - s[i].a) * s[j].b;
  48. sum[i][j] = sum[i][j - 1] + s[j].b;
  49. }
  50. }
  51. for(int i = 1; i <= n; i ++) dp[i][1] = cost[i][n];
  52. for(int j = 2; j <= m; j ++) {
  53. for(int i = n - j + 1; i >= 1; i --) {
  54. dp[i][j] = 1e18;
  55. for(int k = i + 1; k <= n; k ++) {
  56. dp[i][j] = min(dp[i][j], dp[k][j - 1] + cost[i][k - 1]);
  57. }
  58. }
  59. }
  60. limit = dp[1][m];
  61. long long ans2 = sum[1][n];
  62. long long L = 1, R = ans2;
  63. while(L <= R) {
  64. long long mid = (L + R) / 2;
  65. if(check(mid)) ans2 = mid, R = mid - 1;
  66. else L = mid + 1;
  67. }
  68. printf("%lld %lld\n", limit, ans2);
  69. }
  70. return 0;
  71. }

Wannafly挑战赛7 D - codeJan与青蛙的更多相关文章

  1. Wannafly挑战赛7 B - codeJan与旅行

    题目描述 codeJan 非常喜欢旅行.现在有 n 个城市排在一条线上,并且 codeJan 的位置不和任何一个城市的位置重叠.codeJan 想要游览 m 个城市,同时因为时间是不断变化的,游览一个 ...

  2. Wannafly挑战赛25游记

    Wannafly挑战赛25游记 A - 因子 题目大意: 令\(x=n!(n\le10^{12})\),给定一大于\(1\)的正整数\(p(p\le10000)\)求一个\(k\)使得\(p^k|x\ ...

  3. Wannafly挑战赛27

    Wannafly挑战赛27 我打的第一场$Wannafly$是第25场,$T2$竟然出了一个几何题?而且还把我好不容易升上绿的$Rating$又降回了蓝名...之后再不敢打$Wannafly$了. 由 ...

  4. Wannafly 挑战赛 19 参考题解

    这一次的 Wannafly 挑战赛题目是我出的,除了第一题,剩余的题目好像对大部分算法竞赛者来说好像都不是特别友好,但是个人感觉题目质量还是过得去的,下面是题目链接以及题解. [题目链接] Wanna ...

  5. Wannafly挑战赛21A

    题目链接 Wannafly挑战赛21A 题解 代码 #include <cstdio> #include <cmath> #define MAX 1000005 #define ...

  6. Wannafly挑战赛24游记

    Wannafly挑战赛24游记 A - 石子游戏 题目大意: A和B两人玩游戏,总共有\(n(n\le10^4)\)堆石子,轮流进行一些操作,不能进行下去的人则输掉这局游戏.操作包含以下两种: 把石子 ...

  7. Wannafly挑战赛25C 期望操作数

    Wannafly挑战赛25C 期望操作数 简单题啦 \(f[i]=\frac{\sum_{j<=i}f[j]}{i}+1\) \(f[i]=\frac{f[i]}{i}+\frac{\sum_{ ...

  8. Wannafly挑战赛18B 随机数

    Wannafly挑战赛18B 随机数 设\(f_i\)表示生成\(i\)个数有奇数个1的概率. 那么显而易见的递推式:\(f_i=p(1-f_{i-1})+(1-p)f_{i-1}=(1-2p)f_{ ...

  9. Wannafly挑战赛22游记

    Wannafly挑战赛22游记 幸运的人都是相似的,不幸的人各有各的不幸. --题记 A-计数器 题目大意: 有一个计数器,计数器的初始值为\(0\),每次操作你可以把计数器的值加上\(a_1,a_2 ...

随机推荐

  1. 居中div,居中浮动的元素

    定位法:position:absolute 如果子级div有定义宽和高的话就可以用这个方法.注意:margin-top,和margin-left的值均为高和宽值的一半 margin:auto法 这个也 ...

  2. libcurl在mingw下编译

    通过命令提示符进入 curl-7.27.0 文件夹输入 mingw32-make mingw32 进行生成(这里我只需要普通的功能,于是没有加附加的选项)编译完成后,在 lib 文件夹中会有我们需要的 ...

  3. 《Apache HttpClient 4.3开发指南》

    转载自:http://blog.csdn.net/chszs/article/details/16854747 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chs ...

  4. SpringCloud学习(2)——Rest微服务案例

    创建父工程: microservicecloud  创建公共模块api:microservicecloudapi SQL脚本: 此学习路线总共创建3个库, 分别为clouddb01, clouddb0 ...

  5. 2017-2018-2 20179207 《网络攻防技术》第十三周作业 python3实现SM234算法

    国密算法SM234 的python3实现 国家标准 GM/T 0002-2012 <SM4分组密码算法> GM/T 0003.1-2012 <SM2椭圆曲线公钥密码算法 第1部分:总 ...

  6. <LC刷题一>相加为0的数之leetcode1&2&15&16

    --题目导航见页面左上角的悬浮框#目录导航#-- 相似题型导航 1.1 twosum两数之和  ||  2.2 3Sum三数之和  ||  2.3 3Sum Closest最接近的三数之和 ----- ...

  7. Docker 配置国内镜像拉取中心,Configure docker to use faster registries in China.

    Networking in China is really bad when it comes to using some cloud based tools like docker, it's us ...

  8. Python os.path.dirname(__file__) os.path.join(str,str)

    Python os.path.dirname(__file__) Python os.path.join(str,str)   (1).当"print os.path.dirname(__f ...

  9. PHP 快速建立一个对象

    前言 PHP 中的数组(尤其关联数组)是经常使用的 —— 因为方便.在一些框架中也经常见到返回数组格式的配置参数.然而有些时候可能需要对象而非数组类型的配置参数,在查阅网络资料后找到了方法,作以记录. ...

  10. 64_t4

    texlive-hardwrap-svn21396.0.2-33.fc26.2.noarch.rpm 24-May-2017 15:41 35930 texlive-harmony-doc-svn15 ...