Codeforces Round #263 (Div. 2)C(贪心,联想到huffman算法)

数学家伯利亚在《怎样解题》里说过的解题步骤第二步就是迅速想到与该题有关的原型题。(积累的重要性!)

对于这道题,可以发现其实和huffman算法的思想很相似(可能出题人就是照着改编的)。当然最后只是输出cost,就没必要建树什么的了。只要理解了huffman算法构造最优二叉树的思路,就按那么想就知道每个a[i]要加多少次了。

当然这道题没想到这些也可以找出规律的,就是一种贪心思想。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
#define INF 1000000000
#define eps 1e-8
#define pii pair<int,int>
#define LL long long int
const int maxn=310009;
int n;
LL ans=0,a[maxn];
int main()
{
    //freopen("in6.txt","r",stdin);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%I64d",&a[i]);
    }
    sort(a+1,a+n+1);
    for(int i=1;i<=n-1;i++) ans+=(i+1)*a[i];
    ans+=n*a[n];
    cout<<ans<<endl;
}
时间: 2024-10-27 13:40:48

Codeforces Round #263 (Div. 2)C(贪心,联想到huffman算法)的相关文章

Codeforces Round #263 (Div. 1) A B C

Codeforces Round #263 (Div. 1) A:贪心,排个序,然后从后往前扫一遍,计算后缀和,之后在从左往右扫一遍计算答案 B:树形DP,0表示没有1,1表示有1,0遇到0必然合并,0遇到1也必然合并,1遇到0必然合并,1遇到1,必然切断,按照这样去转移即可 C:树状数组,再利用启发式合并,开一个l,r记录当前被子左右下标,和一个flip表示是否翻转 代码: A: #include <cstdio> #include <cstring> #include <

贪心 Codeforces Round #263 (Div. 2) C. Appleman and Toastman

题目传送门 1 /* 2 贪心:每次把一个丢掉,选择最小的.累加求和,重复n-1次 3 */ 4 /************************************************ 5 Author :Running_Time 6 Created Time :2015-8-1 13:20:01 7 File Name :A.cpp 8 *************************************************/ 9 10 #include <cstdio>

Codeforces Round #401 (Div. 2) E 贪心,线段树

Codeforces Round #401 (Div. 2) A 循环节 B 暴力排一下 C 标记出来,但10^5,特耿直地码了个O(n^2)的上去,最气的是在最后3分钟的时候被叉== D 从后往前贪心暴糙一下就好.比赛时一眼瞄出来了不敢写,搞不懂这样竟然不会超时.. E. Hanoi Factory 题意:n个环体,内径a[i],外径b[i],高h[i].当 a[i+1]<b[i]<=b[i+1] 时,第 i 个环体可以堆在第 i+1个环体上.求可以堆出的最高高度. tags:佩服那些大佬,

Codeforces Round #480 (Div. 2) C 贪心 D 数字、思维 E 树上倍增

Codeforces Round #480 (Div. 2) C. Posterized 题意: 给出 n 个数,都是区间 [0,255] 内的数,要你把 [0,255] 划分成多个长度 <=k 的不重叠的子区间.每个数必须包含在一个子区间内,且这个数的价值是这个子区间的左端点.要你输出这 n 数的价值,且这 n 个价值字典序要最小. tags: 首先很明显字典序最小,那对于第 i 个数 p[i] 定它的区间时,左端点肯定要尽可能小.所以我们直接枚举区间 [ p[i]-k+1, p[i] ] 定

Codeforces Round #546 (Div. 2) D 贪心 + 思维

https://codeforces.com/contest/1136/problem/D 贪心 + 思维 题意 你面前有一个队列,加上你有n个人(n<=3e5),有m(m<=个交换法则,假如u在v相邻前面,那么u和v可以交换位置,问你是队列最后一个人的时候你最前可以换到前面哪里 题解 因为相邻才能换,所以最后一个换到前面一定是一步一步向前走,所以不存在还要向后走的情况 设最后一个为u,假设前面有一个能和u换位置的集合,那么需要将这些点尽量往后移动去接u 假设前面有一个不能和u换位置的集合S,

Codeforces Round #547 (Div. 3) F 贪心 + 离散化

https://codeforces.com/contest/1141/problem/F2 题意 一个大小为n的数组a[],问最多有多少个不相交的区间和相等 题解 离散化用值来做,贪心选择较前的区间 代码 #include<bits/stdc++.h> #define M 5000005 #define ll long long #define pb push_back using namespace std; struct N{int l,r;N(int l=0,int r=0):l(l)

Codeforces Round #228 (Div. 1) C 贪心

嘎嘎,今天被一些事耽误了,但是还是A了几个题目,这道题还不错 题目链接: 题意:两个人玩游戏,有N堆纸牌,纸牌上有数字,A每次只能取N堆中的 其中一个的顶部的 纸牌,B只能取N堆中的其中一个底部 的纸牌,A,B都想让自己取的和最大,问最后比分为多少 画了一下,如果某一堆里的 纸牌数量为偶数,发现其实是两个人各分一半,因为如果对方想从这里拿走本来属于自己那半部分的 较大的牌,自己完全来得及阻止的, 接下来就是奇数了,奇数 其实先手者就抢到了中间的一张牌,另外两半还是各自一半,所以 应该以每个奇数堆

Codeforces Round #263 (Div. 2) D. Appleman and Tree 树形dp

链接: http://codeforces.com/contest/462/problem/D 题意: 给定n个点的树, 0为根,下面n-1行表示每个点的父节点 最后一行n个数 表示每个点的颜色,0为白色,1为黑色. 把树分成若干个联通块使得每个联通块有且仅有一个黑点,问有多少种分法(结果mod1e9+7) 题解: 树形dp,每个点有2个状态,已经归属于某个黑点和未归属于某个黑点. 代码: 31 int n; 32 int x[MAXN]; 33 VI G[MAXN]; 34 ll dp[MAX

Codeforces Round #263 (Div.1) B. Appleman and Tree

题目地址:http://codeforces.com/contest/461/problem/B 题目大意:给一棵树.每一个点为白色或黑色.切断一些边,使得每一个连通块有且仅有一个黑点,问划分方案数. 算法讨论:TreeDP. f[x][0..1]表示x所在连通块有0/1个黑点.设y为x的儿子,则DP方程为f[x][1]=f[x][1]*f[y][0]+f[x][1]*f[y][1]+f[x][0]*f[y][1],f[x][0]=f[x][0]*f[y][0]+f[x][0]*f[y][1].