Codeforces 1065C Make It Equal (差分+贪心)

题意:n个塔,第i个塔由$h_i$个cube组成,每次可以切去某高度h以上的最多k个cube,问你最少切多少次,可以让所有塔高度相等

k>=n, n<=2e5

思路:差分统计每个高度i有的方块数nh[i],然后从高到低贪心的切就行了

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
//#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional>

#define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) 

using namespace std;

typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL;

const db eps = 1e-6;
const int mod = 100003;
const int maxn = 2e5+100;
const int maxm = 2e5+100;
const ll inf = 0x3f3f3f3f3f3f3f3f;
const db pi = acos(-1.0);

int nh[maxn];
int main() {
    int n;ll m;
    scanf("%d %lld", &n, &m);
    int vol = 0;
    for(int i = 1; i <= n; i++){
        int c;
        scanf("%d", &c);
        nh[0]++;nh[c+1]--;

    }
    for(int i = 1; i <= maxn; i++){
        nh[i]+=nh[i-1];
    }
    int tmp = 0;
    int ans = 0;
    for(int i = maxn; i >= 0; i--){
        if(nh[i]==n)break;
        if(tmp+nh[i]>m){
            tmp=nh[i];
            ans++;
        }
        else tmp+=nh[i];
    }
    if(tmp>0)ans++;
    printf("%d", ans);
    return 0;
}

原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/9780373.html

时间: 2024-08-22 17:42:17

Codeforces 1065C Make It Equal (差分+贪心)的相关文章

F - Make It Equal CodeForces - 1065C

题目大意:有n座塔,塔高h[i],每次给定高度H对他们进行削切,要求每次削掉的所有格子数不能超过k个,输出最少削几次才能使所有塔的高度相同. 思路一:差分+贪心 对于每一个高度h,用一个数组让1~h的数,每一个都加一.用差分求一下后缀和可以完成. AC code: #include<bits/stdc++.h> using namespace std; typedef long long ll; const ll N=2E5+7; ll arr[N]; int main() { ll n,k;

Codeforces 583 DIV2 Robot&#39;s Task 贪心

原题链接:http://codeforces.com/problemset/problem/583/B 题意: 就..要打开一个电脑,必须至少先打开其他若干电脑,每次转向有个花费,让你设计一个序列,使得总花费最小. 题解: 就傻傻的走就好..从左走到右,再走回来,更新序列和答案就好. 代码: #include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #define MA

Codeforces 442C Artem and Array(stack+贪心)

题目连接:Codeforces 442C Artem and Array 题目大意:给出一个数组,每次删除一个数,删除一个数的得分为两边数的最小值,如果左右有一边不存在则算作0分.问最大得分是多少. 解题思路:首先将连续的a,b,c,a > b && c > b的情况将c掉,获得min(a,b)分,这样处理后数组变成一个递増再递减的序列,除了最大和第二大的取不到,其他数字均可以得分. 样例:4 10 2 2 8 #include <cstdio> #include

Codeforces 18D Seller Bob java大数+贪心

题目链接:点击打开链接 java: import java.math.BigInteger; import java.util.Scanner; public class Main { static int N = 5005; static BigInteger[] er = new BigInteger[N]; static BigInteger E = new BigInteger("2"); static int[] a = new int[N]; static int[] ma

Codeforces 437C The Child and Toy(贪心)

题目连接:Codeforces 437C The Child and Toy 题目大意:孩子有一个玩具,有n个部件组成,m条绳子组成,每条绳子连接两个部件.小孩比较顽皮,要将玩具拆成不可分割的部件,每次剪断一条绳子的代价是该绳子连接的两个部件的权值中较小的值.问说最小的总代价是多少. 解题思路:以为每条边都是要被剪断的,所以将节点按照代价值从大到小排序,每次拿掉权值大的点,与该点连接并且还未剪断的边均用另外点的权值. #include <cstdio> #include <cstring

Codeforces 437D The Child and Zoo(贪心+并查集)

题目链接:Codeforces 437D The Child and Zoo 题目大意:小孩子去参观动物园,动物园分很多个区,每个区有若干种动物,拥有的动物种数作为该区的权值.然后有m条路,每条路的权值为该条路连接的两个区中权值较小的一个.如果两个区没有直接连接,那么f值即为从一个区走到另一个区中所经过的路中权值最小的值做为权值.问,平均两个区之间移动的权值为多少. 解题思路:并查集+贪心.将所有的边按照权值排序,从最大的开始连接,每次连接时计算的次数为连接两块的节点数的积(乘法原理). #in

Codeforces 459E Pashmak and Graph(dp+贪心)

题目链接:Codeforces 459E Pashmak and Graph 题目大意:给定一张有向图,每条边有它的权值,要求选定一条路线,保证所经过的边权值严格递增,输出最长路径. 解题思路:将边按照权值排序,每次将相同权值的边同时加入,维护每个点作为终止点的最大长度即可. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 3

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 1295E]Permutation Separation(线段树+贪心)

[Codeforces 1295E]Permutation Separation(线段树+贪心) 题面 给出一个排列\(p_1,p_2,...p_n\).初始时你需要选择一个位置把排列分成左右两个.然后在两个序列间移动元素使得左边序列的所有元素都比右边的所有元素小.给出每个元素\(p_i\)从一个序列移动到另一个序列的代价\(a_i\). 分析 显然最后得到的序列是小的数在一边,大的数在另一边.设从值为\(i\)的元素处分开之后移动代价为\(ans_i\). 一开始假设所有数都移到右边序列,那么