离散化、贪心、双指针、二分、倍增、构造、位运算

2024-04-03 09:04

本文主要是介绍离散化、贪心、双指针、二分、倍增、构造、位运算,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

八、离散化

1、离散化简介

  • 把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。
  • 离散化是一种将数组的值域压缩,从而更加关注元素的大小关系的算法。
  • 当原数组中的数字很大、负数、小数时(大多数情况下是数字很大),难以将“元素值”表示为”数组下标“,一些依靠下标实现的算法和数据结构无法实现时,我们就可以考虑将其离散化。
  • 离散化数组要求内部是有序的(一般是去重的,当然也存在不去重的方法,但是比较少见),其中可以直接通过离散化下标得到值。

 

例题

        输入一个长度为n的数组An,输出第i个数在数组从小到大排序后的排名,数字大小相同时排名一样。(n<=1e5,Ai<.1e9)

输入:5

           5 4 4 2 1                                     4 3 3 2 1

package 无忧.第二章.基础算法;import java.util.*;public class _08离散化 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();int[] arr = new int[n];int[] a = new int[n];Set<Integer> set = new HashSet<>();for (int i = 0; i < n; i++) {arr[i] = sc.nextInt();a[i] = arr[i];}Arrays.sort(a);int k = 0;Map<Integer,Integer> map = new HashMap<>();for (int i = 0; i < n; i++) {set.add(a[i]);map.put(a[i],set.size());}for (int i = 0; i < n; i++) {System.out.print(map.get(arr[i]) + " ");}}
}

九、贪心

1、贪心的概念

  1. 建立数学模型来描述问题
  2. 把求解的问题分成若干子问题
  3. 对每一字问题求解,得到子问题的局部最优解
  4. 把子问题的解局部最优解合成原来解问题的一个解

总结:从局部最优做到全局最优

例题---谈判

https://www.lanqiao.cn/problems/545/learning/

        在很久很久以前,有n个部落居住在平原上,依次编号为1到n。第i个部落的人数为t_{i}。有一年发生了荒灾。年轻的政治家小兰想要说服所有部落一同应对灾害,他能通过谈判来说服部落进行联合。每次谈判,小蓝只能邀请两个部落参加,花费的金币数量为两个部落的人数之和,谈判的效果是两个部落联合成一个部落(人数为原来两个部落的人数之和)

输入描述:输入的第一行包含一个整数n,表示部落的数量。

                  第二行包含n个正整数,依次表示每个部落的人数。

输出描述:输出一个整数,表示最小花费。

示例:4

           9 1 3 5                 31

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);List<Integer> list = new ArrayList<>();int n = sc.nextInt();for (int i = 0; i < n; i++) {int a = sc.nextInt();list.add(a);}Collections.sort(list);long sum = 0;while (list.size()>1){int a = list.get(0);int b = list.get(1);sum += a + b;list.remove(0);list.remove(0);list.add(a+b);Collections.sort(list);}System.out.println(sum);sc.close();}
}

例题---重新排序

        给定一个数组A和一些查询L{_{i}}R_{i},求数组中第L{_{i}}至第R_{i}个元素的之和。小蓝觉得这个问题很无聊,于是他想重新排列一下数组,使得最终每个查询结果的和尽可能地大。小蓝想知道相比原数组,所有查询结果的总和最多可以增加多少?

输入格式:输入第一行包含一个整数n。

                  第二行包含n个整数A_{1},A_{2},...,A_{n},相邻两个整数之间用一个空格分隔。

                  第三行包含一个整数m表示查询的数目。

                  接下来m行,每行包含两个整数L{_{i}}R_{i},相邻两个整数之间用一个空格分隔。

输出格式:输出一行包含一个整数表示答案。

示例:5

           1 2 3 4 5

           2

           1 3

            2 5                                                          4

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.lang.invoke.MethodHandles;
import java.util.Arrays;
import java.util.StringTokenizer;public class Main {public static void main(String[] args) {MyScanner sc = new MyScanner();int n = sc.nextInt();int[] arr = new int[n];for (int i = 0; i < n; i++) {arr[i] = sc.nextInt();}int q = sc.nextInt();int[] d = new int[n];while(q-->0){int l = sc.nextInt()-1;

这篇关于离散化、贪心、双指针、二分、倍增、构造、位运算的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/872482

相关文章

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

hdu2289(简单二分)

虽说是简单二分,但是我还是wa死了  题意:已知圆台的体积,求高度 首先要知道圆台体积怎么求:设上下底的半径分别为r1,r2,高为h,V = PI*(r1*r1+r1*r2+r2*r2)*h/3 然后以h进行二分 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#includ

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

usaco 1.3 Barn Repair(贪心)

思路:用上M块木板时有 M-1 个间隙。目标是让总间隙最大。将相邻两个有牛的牛棚之间间隔的牛棚数排序,选取最大的M-1个作为间隙,其余地方用木板盖住。 做法: 1.若,板(M) 的数目大于或等于 牛棚中有牛的数目(C),则 目测 给每个牛牛发一个板就为最小的需求~ 2.否则,先对 牛牛们的门牌号排序,然后 用一个数组 blank[ ] 记录两门牌号之间的距离,然后 用数组 an

uva 575 Skew Binary(位运算)

求第一个以(2^(k+1)-1)为进制的数。 数据不大,可以直接搞。 代码: #include <stdio.h>#include <string.h>const int maxn = 100 + 5;int main(){char num[maxn];while (scanf("%s", num) == 1){if (num[0] == '0')break;int len =

poj 3190 优先队列+贪心

题意: 有n头牛,分别给他们挤奶的时间。 然后每头牛挤奶的时候都要在一个stall里面,并且每个stall每次只能占用一头牛。 问最少需要多少个stall,并输出每头牛所在的stall。 e.g 样例: INPUT: 51 102 43 65 84 7 OUTPUT: 412324 HINT: Explanation of the s

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

poj 3104 二分答案

题意: n件湿度为num的衣服,每秒钟自己可以蒸发掉1个湿度。 然而如果使用了暖炉,每秒可以烧掉k个湿度,但不计算蒸发了。 现在问这么多的衣服,怎么烧事件最短。 解析: 二分答案咯。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <c

poj 3258 二分最小值最大

题意: 有一些石头排成一条线,第一个和最后一个不能去掉。 其余的共可以去掉m块,要使去掉后石头间距的最小值最大。 解析: 二分石头,最小值最大。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <c

poj 2594 二分图最大独立集

题意: 求一张图的最大独立集,这题不同的地方在于,间接相邻的点也可以有一条边,所以用floyd来把间接相邻的边也连起来。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <sta