HDU 4923 Room and Moor (单调栈)
题意:
给你一个A数列,让你求一个单调递增的B数列(0<=bi<=1),使得sum{(ai-bi)^2}最小。
思路:
很明显,如果A = 0...01...1,那么bi=ai即可。
可以证明,如果 A = 1...10...0,那么所有bi达到同一个值的时候取得最优值。 假设 ai = 1, aj = 0, 那么 i<j ,所以bi<=bj。 若bi != bj,那么增大bi的值,或者减小bj的值都可以得到更优的结果。 所以,bi=bj。
所以,如果A数列里面出现了形如 "1...10...0"的部分,我们都可以把它当做同一段处理。因为他们对应的bi值一定相同。
这样,我们可以得到一个中间序列,x1, ..., x1, x2, ..., x2, ..., xm, ...xm. 我们可以把它简化为,x1, ..., xm。其中 xi对应着每一段的最优值。
我们可以发现,这里的xi不一定单调递增。 然后我们仿照上面的证明,知道当有相邻两段的xi递减时,会在他们所有的bi相等时取得最优值。因此,我们可以把这两段合并,求出一个满足单调性的值。
所以,最后的B序列一定是这样:y1, ..., y1, ..., ym, ..., ym。所以我们可以用一个单调栈来维护所有的bi值。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <functional>
#include <time.h> using namespace std; typedef pair<double, int> PDI; const int INF = <<;
const int MAXN = (int) 1e5+; int n;
int a[MAXN];
double b[MAXN]; PDI sk[MAXN]; //栈
int tail; //栈顶指针 void solve() {
tail = ; //栈初始化 for (int i = ; i < n; i++) {
sk[tail++] = make_pair(1.0*a[i], ); //当前点入栈
while (tail> && sk[tail-].first<=sk[tail-].first) { //如果栈不满足单调性,合并最上面两个节点
int cnt = sk[tail-].second+sk[tail-].second;
double tmp = (sk[tail-].first*sk[tail-].second+sk[tail-].first*sk[tail-].second)/cnt;
sk[tail-] = make_pair(tmp, cnt);
tail--;
}
}
//求出bi
for (int i = , j = ; i < tail; i++)
for (int k = ; k < sk[i].second; k++)
b[j++] = sk[i].first;
//求出结果
double ans = ;
for (int i = ; i < n; i++)
ans += (a[i]-b[i])*(a[i]-b[i]);
printf("%f\n", ans);
} int main() {
#ifdef Phantom01
freopen("HDU4923.txt", "r", stdin);
#endif //Phantom01 int T;
scanf("%d", &T);
while (T--) {
scanf("%d", &n);
for (int i = ; i < n; i++)
scanf("%d", &a[i]);
solve();
} return ;
}
HDU 4923
HDU 4923 Room and Moor (单调栈)的更多相关文章
- hdu 4923 Room and Moor (单调栈+思维)
题意: 给一个0和1组成的序列a,要构造一个相同长度的序列b.b要满足非严格单调,且 值为0到1的实数.最后使得 sum((ai-bi)^2)最小. 算法: 首先a序列開始的连续0和末尾的连续1是能 ...
- HDU 4923 Room and Moor(推理+栈维护)
HDU 4924 Room and Moor 题目链接 题意:给定一个01组成的a序列.要求一个b序列,b序列每一个数值为[0, 1]之间的数,而且b序列为非递减序列,要求∑(ai−bi)2最小,求这 ...
- HDU 5875 H - Function 用单调栈水过了
http://acm.hdu.edu.cn/showproblem.php?pid=5875 单调栈,预处理to[i]表示第一个比a[i]小的数字,一直跳就可以. 这题是数据水而已. 这里学习下单调栈 ...
- hdu 5696 区间的价值 单调栈+rmq
区间的价值 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem D ...
- HDU 4923 Room and Moor (多校第六场C题) 单调栈
Problem Description PM Room defines a sequence A = {A1, A2,..., AN}, each of which is either 0 or 1. ...
- hdu 4923 Room and Moor [ 找规律 + 单调栈 ]
传送门 Room and Moor Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Oth ...
- HDU 4923 Room and Moor
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4923 解题报告:给出一个长度为n的只包含0和1的序列,是否存在一个序列Bi满足一下条件: 1. ...
- HDU 4923 Room and Moor(瞎搞题)
瞎搞题啊.找出1 1 0 0这样的序列,然后存起来,这样的情况下最好的选择是1的个数除以这段的总和. 然后从前向后扫一遍.变扫边进行合并.每次合并.合并的是他的前驱.这样到最后从t-1找出的那条链就是 ...
- HDU - 5033: Building(单调栈 ,求一排高楼中人看楼的最大仰角)
pro:现在在X轴上有N个摩天大楼,以及Q个人,人和大楼的坐标各不相同,保证每个人左边和右边都有楼,问每个人能看到天空的角度大小. sol:不难想到就是维护凸包,此题就是让你模拟斜率优化,此处没有斜率 ...
随机推荐
- 微信重排版 URL
http://qbview.url.cn/getResourceInfo?appid=62&url=https%3A%2F%2Fcodepen.io%2Fbenjamminf%2Ffull%2 ...
- 用MyBatis进行数据库的增删改查
前提是MyBatis环境部署好了,参考地址: https://www.cnblogs.com/package-java/p/10316536.html 为了方便演示,我提前在数据库插入了数据方便查询 ...
- 关于wdsl
WSDL元素 WSDL元素基于XML语法描述了与服务进行交互的基本元素: Type(消息类型):数据类型定义的容器,它使用某种类型系统(如XSD). Message(消息):通信数据的抽象类型化定义, ...
- Vue中两种传值方式
第一种:通过url传参,直接在地址后加? ,通过this.$route.query对象获取 第二种:通过路由传参,修改路由,通过this.$route.params对象获取
- POJ-1113 Wall 计算几何 求凸包
题目链接:https://cn.vjudge.net/problem/POJ-1113 题意 给一些点,求一个能够包围所有点且每个点到边界的距离不下于L的周长最小图形的周长 思路 求得凸包的周长,再加 ...
- python 正则表达式与re模块
一.正则表达式 用途 用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑. #### 简单地说 就是用于字符串匹配的 字符组 在 ...
- 洛谷 P1541 乌龟棋 (四维费用背包)
一开始直接用01背包 后来发现这个物品和位置有关. 也就是价值不是固定的 后来看了题解 看了卡片最多就4 所以这是一个四维费用的背包, 每一维是卡片的数量 价值就是当前的位置的价值. 但是与常规的背包 ...
- 题解 P3413 【SAC#1 - 萌数】
这道题刚开始正向思维,然后处理重复的时候咕咕了. 参考了@巨型方块 大佬的题解后AC了,在这里就说几个我觉得比较重要或是容易被忽略的点,然后补充一些跳过的证明. 这道题的状态可以设为$dp[i][j] ...
- 洛谷 P2730 魔板 Magic Squares
P2730 魔板 Magic Squares 题目背景 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 题目描述 ...
- 为什么不能往Android的Application对象里存储数据
在一个App里面总有一些数据需要在多个地方用到.这些数据可能是一个 session token,一次费时计算的结果等.通常为了避免activity之间传递对象的开销 ,这些数据一般都会保存到持久化存储 ...