HDU 4923 Room and Moor(推理+栈维护)
2024-09-04 15:41:49
HDU 4924 Room and Moor
题意:给定一个01组成的a序列。要求一个b序列,b序列每一个数值为[0, 1]之间的数,而且b序列为非递减序列,要求∑(ai−bi)2最小,求这个最小值
思路:推理,非常easy看出,开头一段的0和末尾一段的1等于没有。然后中间每段相似111000这样1在前,0在后的序列。都能够列出一个公式,非常easy推出选择的x为共同的一个值,为1的个数/(1的个数+0的个数)a,那么问题就变成要维护一个递增的x。利用一个栈去做维护,假设遇到一个位置递减了。那么就把它和之前的段进行合并,维护栈中递增,最后把栈中元素都拿出来算一遍就是答案了
代码:
#include <cstdio>
#include <cstring>
#include <stack>
using namespace std; const int N = 100005;
const double eps = 1e-8; int t, n, a[N];
struct Seg {
double one, zero, x;
Seg() {}
Seg(double one, double zero, double x) {
this->one = one;
this->zero = zero;
this->x = x;
}
} s[N]; double cal(double one, double zero) {
return one / (one + zero);
} double solve(int n) {
int sn = 0;
int one = 0, zero = 0, now = 0;
while (now < n && !a[now]) {now++;}
while (n >= 0 && a[n]) n--;
if (now > n) return 0.0;
while (now <= n) {
double one = 0, zero = 0;
while (a[now]) {
one += 1;
now += 1;
}
while (now <= n && !a[now]) {
zero += 1;
now += 1;
}
s[sn].one = one;
s[sn].zero = zero;
s[sn++].x = cal(one, zero);
}
stack<Seg> st;
st.push(s[0]);
for (int i = 1; i < sn; i++) { Seg now = s[i]; while (!st.empty() && st.top().x - now.x > -eps) {
Seg pre = st.top();
st.pop();
pre.one += now.one;
pre.zero += now.zero;
pre.x = cal(pre.one, pre.zero);
now = pre;
}
st.push(now); }
double ans = 0;
while (!st.empty()) {
Seg now = st.top();
st.pop();
ans += (1 - now.x) * (1 - now.x) * now.one + now.x * now.x * now.zero;
}
return ans;
} int main() {
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
printf("%.6lf\n", solve(n - 1));
}
return 0;
}
最新文章
- Linux下解压命令大全 解压缩 tar bz2 zip tar.gz gz
- PHP之数组array
- FAILED java.lang.IllegalArgumentException: java.net.URISyntaxException: Relative path in absolute URI:hdfs:192.*
- 【shell】通配符
- ArcGIS Engine栅格数据使用总结
- linux中ctrl+z、ctrl+d和ctrl+c的区别
- 线程知识-ThreadLocal使用详解
- Windows、Linux -- 远程登录、文件传输、文件共享
- java中String相等问题
- NSURLSession http转Https
- Dynamics CRM项目实例之六:积分管理,汇总字段,计算字段,快速查看视图
- python中的 list (列表)append()方法 与extend()方法的用法 和 区别
- java.lang.NumberFormatException 错误及解决办法
- Shell 脚本进阶2
- java compareTo() 用法注意点
- 字体在win10下显示模糊,有锯齿
- Linux 开启定时计划任务
- css 基础2
- python的XML处理模块ElementTree
- HTML5 Canvas ( 圆和切点曲线的绘制 ) arc, arcTo
热门文章
- kb-07-RMQ线段树--07(动态规划)
- Github管理 第二步:Eclipse+Github,管理Java Project版本(First Commit)
- RestAssured打印日志到文件中的方法
- 【BZOJ1059】矩阵游戏(二分图最大匹配)
- Codeforces878E. Numbers on the blackboard
- 如何用github展示前端页面
- hdu 1565&;hdu 1569(网络流--最小点权值覆盖)
- LeetCode OJ--Remove Duplicates from Sorted Array
- CSS3-文本渐变色
- 常用函数和STL