zoukankan      html  css  js  c++  java
  • Codeforces Round #618 (Div. 2) E

    Problem

    Codeforces 题目地址

    Solution

    看完qsc大佬的题解后才发现真的是考场降智啊!!!是真的蠢啊!!!

    假设前 (k-1) 个数已经通过调整达到了最小字典序,调整成了 (m) 块,第 (i) 的数(因为都是一样的就叫一块)是 (x_i)。很显然满足一个条件:(x_1 < x_2 < ... < x_m)

    现在加入第 (k) 个数

    (k) 个数的左边是 (x_m) 这一块,我们只要比较一下 (a_k)(x_m) 的大小。如果 (a_k < x_m),说明把 (a_k) 加入到 (x_m) 可以更优(平均数更小),这时 (x_m) 发生了改变,我们要继续类似地比较 (x_m)(x_{m-1}),直到满足条件。如果 (a_k > x_m)(a_k) 又可以作为单独的一块加入到后面,变成 (x_{m+1})

    昨晚还瞎想用啥数据结构,实际上完全不需要。。。

    Code

    Talk is cheap.Show me the code.

    #include<bits/stdc++.h>
    using namespace std;
    inline int read() {
    	int x=0,f=1; char ch=getchar();
    	while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    	while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); }
    	return x * f;
    }
    const int N = 1e6+7;
    int n,tot;
    int L[N];
    double a[N],b[N];
    int main()
    {
    	n = read();
    	for(int i=1;i<=n;++i)
    		a[i] = read();
    	for(int i=1;i<=n;++i) {
    		b[++tot] = a[i]; L[tot] = 1;
    		while(tot>=1 && b[tot]<b[tot-1]) {
    			b[tot-1] = (L[tot-1]*b[tot-1]+L[tot]*b[tot]) / (L[tot-1] + L[tot]);
    			L[tot-1] += L[tot];
    			--tot;
    		}
    	}
    	for(int i=1;i<=tot;++i)
    		for(int j=1;j<=L[i];++j)
    			printf("%.9lf
    ",b[i]);
    	return 0;
    }
    

    Summary

    这题的这种解法灵活地避开了数据结构这个死胡同,其核心思想是数学归纳法 + 贪心

    这启发我们遇到类型的问题可以先不管全局,考虑如果前面已经符合条件,第 (k) 个应该怎么处理?

    结合题目是最优化问题,考虑合适的贪心。

  • 相关阅读:
    阿里云前端周刊
    在没有DOM操作的日子里,我是怎么熬过来的(中)
    【php学习】数组操作
    App之百度云推送
    L2-008. 最长对称子串
    整数划分问题之递归法
    分治法之归并排序(递归+分治)
    L2-005. 集合相似度
    分治法之棋盘覆盖问题
    L2-003. 月饼
  • 原文地址:https://www.cnblogs.com/BaseAI/p/12291569.html
Copyright © 2011-2022 走看看