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

输入描述:

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

输出描述:

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

输入

2
3 1
1 1
2 2
3 3
3 2
1 1
4 2
2 3

输出

8 6
3 4

说明

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

备注:

输入保证a[i] ≠a[j](i ≠j),1≤m≤n≤100,1≤a[i],b[i]≤106。

题解

$dp$,二分。

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

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

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

#include <bits/stdc++.h>
using namespace std; const int maxn = 100 + 10;
int T, n, m;
struct X {
int a, b;
}s[maxn];
long long cost[maxn][maxn];
long long dp[maxn][maxn];
long long sum[maxn][maxn];
long long limit; bool cmp(const X& a, const X& b) {
return a.a < b.a;
} int check(long long mid) {
for(int i = 1; i <= n; i ++) {
dp[i][1] = 1e18;
if(sum[i][n] <= mid) dp[i][1] = cost[i][n];
}
for(int j = 2; j <= m; j ++) {
for(int i = n - j + 1; i >= 1; i --) {
dp[i][j] = 1e18;
for(int k = i + 1; k <= n; k ++) {
if(dp[k][j - 1] != 1e18 && sum[i][k - 1] <= mid) {
dp[i][j] = min(dp[i][j], dp[k][j - 1] + cost[i][k - 1]);
}
}
}
}
if(limit == dp[1][m]) return 1;
return 0;
} int main() {
scanf("%d", &T);
while(T --) {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++) {
scanf("%d%d", &s[i].a, &s[i].b);
}
sort(s + 1, s + 1 + n, cmp);
for(int i = 1; i <= n; i ++) {
for(int j = i; j <= n; j ++) {
cost[i][j] = cost[i][j - 1] + 1LL * (s[j].a - s[i].a) * s[j].b;
sum[i][j] = sum[i][j - 1] + s[j].b;
}
}
for(int i = 1; i <= n; i ++) dp[i][1] = cost[i][n];
for(int j = 2; j <= m; j ++) {
for(int i = n - j + 1; i >= 1; i --) {
dp[i][j] = 1e18;
for(int k = i + 1; k <= n; k ++) {
dp[i][j] = min(dp[i][j], dp[k][j - 1] + cost[i][k - 1]);
}
}
}
limit = dp[1][m];
long long ans2 = sum[1][n];
long long L = 1, R = ans2;
while(L <= R) {
long long mid = (L + R) / 2;
if(check(mid)) ans2 = mid, R = mid - 1;
else L = mid + 1;
}
printf("%lld %lld\n", limit, ans2);
}
return 0;
}

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. Jenkins使用教程之管理节点

    通常的情况下在我们的一个项目当中,项目会有多个分支系统,而我们不可能为每个分支系统都配置一个jenkins服务,这样既浪费资源,也增加构建部署的难度,为了解决这个问题jenkins给使用者提供了非常强 ...

  2. Python学习笔记(三十九)— 内置模块(8)XML基础

    摘抄自:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432002075 ...

  3. Handlerbars基础笔记

    此笔记摘抄于杨元的博客(http://www.cnblogs.com/iyangyuan/archive/2013/12/12/3471227.html) 引入 <script type=&qu ...

  4. 【leetcode 简单】 第八题 删除排序数组中的重复项

    给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 示例 1 ...

  5. 爬虫实战--使用Selenium模拟浏览器抓取淘宝商品美食信息

    from selenium import webdriver from selenium.webdriver.common.by import By from selenium.common.exce ...

  6. Verilog笔记.2.数字逻辑电路

    1.数字逻辑电路的种类:1) 组合逻辑:输出只是当前输入逻辑电平的函数(有延时),与电路的原始状态无关的逻辑电路.也就是说,当输入信号中的任何一个发生变化时,输出都有可能会根据其变化而变化,但与电路目 ...

  7. AJAX的前世今生与未来

    一.通过三个问答来认识一下Ajax 什么是Ajax? Ajax是Asynchronous Javascript And XML的缩写,它是一种技术. Ajax有什么用? 这一技术能够向服务器请求额外的 ...

  8. jQuery实现简单前端搜索功能

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. MongoDB 3.4.2 配置 CentOS 6.5 远程连接

    1.新建用户 db.createUser({user: 'test', pwd: 'myPassword', roles: [{role: 'readWrite', db: 'test_db'}]}) ...

  10. 大图片上传(ImageIO,注意有的图片不能上传时因为他是tiff格式)

    一下是必要的: 1.enctype="multipart/form-data" 2. //不要使用myeclipse自动生成的get.set方法(struts2中的用法) publ ...