hdu4923 f(A,B)分段处理
来源:互联网 发布:wifi监控器软件下载 编辑:程序博客网 时间:2024/05/22 16:02
题意:
给你序列A,让你构造序列B然后求出最小的f(A <B),其中A 是0,或者1组成的,而B是[0,1]的实数,f(A,B) = 求和(i从1到n) (Ai - Bi)^ 2.
思路:
首先有一点很明确,那就是我们可以消除面连续的0,和后面连续的1,一开始我的想法是直接求中间部分的平均数, 然后就前面的连续0不用管,后面的连续1不用管,然后中间的部分就是平均数,结果妥妥的WA了,其实正解是分段处理,分成这样的 111000,10
,1110,1111100000...就是断成一些连续1加连续0组成的小段,然后对于当前的这一段的最优就是当前这段的平均数,但是有一点要注意,题目要求的是非递减顺序,那么如果当前的这一段的平均数比前面的那一段的小,我们就得把一段和上一段合并,合并之后如果还比上上一段小,那么在合并(这个地方可以用一个栈,比较方便写),最后在根据剩下的段数来计算答案,既保证了最小,有保证了上升。
给你序列A,让你构造序列B然后求出最小的f(A <B),其中A 是0,或者1组成的,而B是[0,1]的实数,f(A,B) = 求和(i从1到n) (Ai - Bi)^ 2.
思路:
首先有一点很明确,那就是我们可以消除面连续的0,和后面连续的1,一开始我的想法是直接求中间部分的平均数, 然后就前面的连续0不用管,后面的连续1不用管,然后中间的部分就是平均数,结果妥妥的WA了,其实正解是分段处理,分成这样的 111000,10
,1110,1111100000...就是断成一些连续1加连续0组成的小段,然后对于当前的这一段的最优就是当前这段的平均数,但是有一点要注意,题目要求的是非递减顺序,那么如果当前的这一段的平均数比前面的那一段的小,我们就得把一段和上一段合并,合并之后如果还比上上一段小,那么在合并(这个地方可以用一个栈,比较方便写),最后在根据剩下的段数来计算答案,既保证了最小,有保证了上升。
#include<stdio.h>#include<string.h>#include<stack>using namespace std;typedef struct{ double s0 ,s1;}NODE;int num[110000];NODE node[110000];int main (){ int n ,t ,i ,s11 ,mk; scanf("%d" ,&t); while(t--) { scanf("%d" ,&n); for(s11 = 0 ,i = 1 ;i <= n ;i ++) { scanf("%d" ,&num[i]); if(num[i]) s11 ++; } for(mk = n + 1 ,i = 1 ;i <= n ;i ++) if(num[i]) {mk = i;break;} if(s11 == n || mk == n + 1) { puts("0.000000"); continue; } int tt = 0; double s1 = 0 ,s0 = 0; num[n+1] = 1; for(i = mk ;i <= n ;i ++) { if(num[i]) s1 ++; else s0 ++; if(!num[i] && num[i+1]) { node[++tt].s1 = s1; node[tt].s0 = s0; s1 = s0 = 0; } } stack<NODE>st; NODE xin ,tou; for(i = 1 ;i <= tt ;i ++) { if(st.empty()) { st.push(node[i]); continue; } xin = node[i]; tou = st.top(); double tp = tou.s1 / (tou.s1 + tou.s0); double xp = xin.s1 / (xin.s1 + xin.s0); if(xp < tp) { while(1) { tou = st.top(); st.pop(); xin.s1 += tou.s1; xin.s0 += tou.s0; if(st.empty()) { st.push(xin); break; } tou = st.top(); tp = tou.s1 / (tou.s1 + tou.s0); xp = xin.s1 / (xin.s1 + xin.s0); if(xp >= tp) { st.push(xin); break; } } } else st.push(node[i]); } double ans = 0; while(!st.empty()) { NODE tou = st.top(); st.pop(); double tp = tou.s1 / (tou.s1 + tou.s0); ans += (1 - tp) * (1 - tp) * tou.s1 + tp * tp * tou.s0; } printf("%.6lf\n" ,ans); } return 0;}
0 0
- hdu4923 f(A,B)分段处理
- F a^b
- #define f(a, b) a##b
- #define f(a, b) a##b
- #define f(a, b) a##b
- #define f(a, b) a##b
- 假设字符串为 A|B|C|D|E|F|G|H|aaa 处理后获取 A|B|,C|D|E|,F|G|H|,aaa
- 求A*f(A,B,n-1)+B*f(A,B,n-2))%7;
- f(A∩B) 向左 f(A) ∩ f(B) 的证明
- A b c d e f g
- 问题 F: A+B和C (15)
- A + B 字符串处理
- 字符串专题:F - Oulipo (A包含多少次B?KMP)
- Codeforces 630F Selection of Personnel ( C(a,b) )
- Educational Codeforces Round 9 A B C D F
- 练习一A+B+C+D+E+F
- Scala实现a~b f(x)函数
- A(B(D,E),C(F,G))【未整理】
- Maven教程初级篇02:pom.xml配置初步
- 一元两次方程求解
- C#模拟键盘事件
- 享受两分钟亲临大海的感觉(放松自己!)
- 16_break_continue语句
- hdu4923 f(A,B)分段处理
- 一步一步入门机器学习之五:机器学习自学指南
- Java中的回车换行符/n /r /t
- 17_exit()函数
- 垃圾回收机制
- 【UVa】10755 Garbage Heap 三维前缀和
- #define和typedef
- Maven教程初级篇03: 创建Web应用
- 18_有关循环结构的综合实例