HDU 4924 Room and Moor

题目链接

题意:给定一个01组成的a序列。要求一个b序列,b序列每一个数值为[0, 1]之间的数,而且b序列为非递减序列,要求∑(aibi)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;
}

最新文章

  1. Linux下解压命令大全 解压缩 tar bz2 zip tar.gz gz
  2. PHP之数组array
  3. FAILED java.lang.IllegalArgumentException: java.net.URISyntaxException: Relative path in absolute URI:hdfs:192.*
  4. 【shell】通配符
  5. ArcGIS Engine栅格数据使用总结
  6. linux中ctrl+z、ctrl+d和ctrl+c的区别
  7. 线程知识-ThreadLocal使用详解
  8. Windows、Linux -- 远程登录、文件传输、文件共享
  9. java中String相等问题
  10. NSURLSession http转Https
  11. Dynamics CRM项目实例之六:积分管理,汇总字段,计算字段,快速查看视图
  12. python中的 list (列表)append()方法 与extend()方法的用法 和 区别
  13. java.lang.NumberFormatException 错误及解决办法
  14. Shell 脚本进阶2
  15. java compareTo() 用法注意点
  16. 字体在win10下显示模糊,有锯齿
  17. Linux 开启定时计划任务
  18. css 基础2
  19. python的XML处理模块ElementTree
  20. HTML5 Canvas ( 圆和切点曲线的绘制 ) arc, arcTo

热门文章

  1. kb-07-RMQ线段树--07(动态规划)
  2. Github管理 第二步:Eclipse+Github,管理Java Project版本(First Commit)
  3. RestAssured打印日志到文件中的方法
  4. 【BZOJ1059】矩阵游戏(二分图最大匹配)
  5. Codeforces878E. Numbers on the blackboard
  6. 如何用github展示前端页面
  7. hdu 1565&amp;hdu 1569(网络流--最小点权值覆盖)
  8. LeetCode OJ--Remove Duplicates from Sorted Array
  9. CSS3-文本渐变色
  10. 常用函数和STL