第13章贪心算法

server/2025/3/27 10:40:33/

算法>贪心算法

局部最优求得总体最优

适用于桌上有6张纸币,面额为100 100 50 50 50 10,问怎么能拿走3张纸币,总面额最大?—拿单位价值最高的

  1. 只关注局部最优----关注拿一张的最大值
  2. 拆解-----拿三次最大的纸币

不适用于桌面三件物品,每个物品都有重量和价值,

w v

6 9

5 7

3 3

承重为8,求不超过背包承重情况下最大价值

  1. 只能选一件,能不能得到最大值----选 6 9
  2. 还剩下二,能选第二件吗?不能选

所以不适用,因为不能局部最优求得总体最优

算法>贪心算法的设计就是一次一次用偏序关系证明贪心策略

偏序关系

在数学中,偏序集合是有序理论中,指配备了部分排序关系的集合(集合没有顺序,但加了一个用于排序的关系),将排序,顺序或排列这个元素的直觉概念抽象化。

使用偏序关系的传递性:xRy,yRz–>xRz,局部最优使得全局最优

例题1-国王游戏

排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。

国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。

输出一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的金币数。

C[i]=A[j]/B[i] :累乘从0到i-1

微扰:调整i和i+1位置的大臣,观察序列前后的变化:

微调的两个元素A[i]和A[i+1]只会改变他们两本身:所以微调后的C[i]'和C[i+1]'同时小于C[i+!]

A[i]xB[i] >= A[i+1]xB[i+1] :越小越往前,越大越往后

#include <iostream>
#include <algorithm>using namespace std;
#define MAX_N 1000
int a[MAX_N+5],b[MAX_N+5],ind[MAX_N+5]; //使用ind不对原数组排序,对下标数组排序
void acm_1_6_paixu_GuowangYouxi_test(){
//    A[i]xB[i] >= A[i+1]xB[i+1] :越小越往前,越大越往后int n;cin >> n;for(int i=0;i<=n;i++){cin >>a[i]>>b[i]; //左右手ind[i]=i;}sort(ind+1,ind+n+1,[&](int i,int j)->bool{return a[i]*b[i]<a[j]*b[j];});//统计大臣获得的最多金币数量int p=a[0],ans=0;for (int i=1;i<=n;i++){if(p/b[ind[i]]) //ind[i]表示排完序之后大臣的编号ans=p/b[ind[i]];p*=a[ind[i]];}cout << ans<<endl;}
int main(){acm_1_6_paixu_GuowangYouxi_test();return  0;
}
def acm_1_6_paixu_GuowangYouxi_test():n=int(input())a=list(range(n+1))b=list(range(n+1))ind=list(range(n+1))for i in range(n+1):a[i],b[i]=list(map(int,input().split()))ind[i]=iind[1:]=sorted(ind[1:],key=lambda i:a[i]*b[i]) #按照a[i]*b[i]从小到大排序ans=0p=a[0]for i in range(1,n+1):if(p//b[ind[i]]>ans):ans=p//b[ind[i]]p*=a[ind[i]]  #左边所有大臣左手累乘print(int(ans))
acm_1_6_paixu_GuowangYouxi_test()

最大整数

局部最优:a+b > b+a

arr.sort(key=cmp_to_key(cmp2))

from functools import cmp_to_key
def cmp2(a,b):if a + b > b + a: #大于return -1elif a + b < b + a: #小于return 1else:return 0 #相等
def test():n=int(input())arr = input().split()arr.sort(key=cmp_to_key(cmp2))print("".join(arr))
test()
#include <string.h>
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;
bool cmp(const string &a,const string &b){return a+b > b+a;
}
int main(){vector<string> arr;string s;int n;cin >> n;for (int i=0;i<n;i++){cin >> s;arr.push_back(s);}sort(arr.begin(),arr.end(),cmp);for(int i=0;i<n;i++){cout <<arr[i];}cout <<endl;}

删除

每次删除一位,保证删除一位后得到的结果位删除一位最小值

#include <iostream>
using namespace std;
#define MAX_N 500int main(){char s[MAX_N+5];int k;cin >> s >>k;for(int i=0;i<k;i++){ //进行k次删除,每次删除一位int j=0;//留下n-1位的最小值while(s[j+1] !='\0' && s[j] <= s[j+1]){++j;}//12343 //得到第一个逆序位高位4while(s[j]) s[j]=s[j+1],j++; //后面的向前移动//完成一轮删除}for(int i=0,flag=1;s[i];i++){if(s[i]=='0' && flag){//首位0不输出//flag表示有没有输出过数字continue;}cout << s[i];flag=0;}cout <<endl;return  0;
}
#!/usr/bin/python3
# _*_ coding: utf-8 _*_
#
# Copyright (C) 2024 - 2024 Cry, Inc. All Rights Reserved 
#
# @Time    : 2024/4/10 11:47
# @Author  : Cry
# @File    : 删数、.py
# @IDE     : PyCharms=input()
n=int(input())
for i in range(n):for j in range(len(s)+1):if j+1==len(s):s=s[:j]+s[j+1:]breakif s[j]>s[j+1]:s=s[:j]+s[j+1:]break
print(int(s))

HZOJ 503独木舟

每次找最重和最轻的坐在一起

能坐在一起就一起走

不能坐在一起,就只让重的坐一条船

//
// Created by cry on 2024/4/10.
//
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;void acm_1_13_tanxin_DumuZHou_test(){int w,n;cin >>w >> n;vector<int> arr(n);for(int i=0;i<n;i++){cin >> arr[i];}sort(arr.begin(),arr.end());int i=0,j=n-1,cnt=0; // i为最轻的 j为最重的while(i<j){//最轻的和最重的能不能坐一个船if(arr[i]+arr[j]<=w){i++,j--;}elsej--;cnt+=1;}if(i==j) cnt+=1; //还剩一个人cout << cnt<<endl;
}
#!/usr/bin/python3
# _*_ coding: utf-8 _*_
#
# Copyright (C) 2024 - 2024 Cry, Inc. All Rights Reserved 
#
# @Time    : 2024/4/10 12:22
# @Author  : Cry
# @File    : 独木舟.py
# @IDE     : PyCharmw=int(input())
n=int(input())
arr=list(range(n))
for i in range(n):arr[i]=int(input())
arr=sorted(arr)
i=0
j=n-1
cnt=0
while(i<j):if(arr[i]+arr[j]<=w):i+=1j-=1else:j-=1cnt+=1
if(i==j):cnt+=1
print(cnt)

http://www.ppmy.cn/server/178706.html

相关文章

c++高精度减法

我们在计算高精度减法的时候其实和高精度加法是有着异曲同工之处的&#xff0c;唯一需要改变的就是借位的逻辑还有数字大小的逻辑 下来我们来写一写高精度减法 刚开始呢我们还是和高精度加法一样高精度加法&#xff0c;我们需要先反转再计算 代码如下: int main() {string …

selenium(鼠标操作、页面操作、用例设计)

ActionChains类&#xff08;鼠标操作&#xff09; 常用于模拟鼠标的行为&#xff0c;比如单击、双击、拖拽等行为 click(on_elementNone) --- 鼠标单击 double_click(on_elementNone) --- 双击 context_click(on_elementNone) --- 右击…

系统设计类问题回答模板

在系统设计类问题的面试中,一个好的回答不仅仅体现了候选人的技术能力,还能展现其对问题本质的理解、清晰的沟通技巧以及解决方案的条理性和可扩展性。以下是一个通用的回答模板,以及回答技巧、白板演示的指导方法,并会结合实际案例提供一些示例。 一、系统设计类问题回答的…

2025-03-23 学习记录--C/C++-C语言 sprintf()实现将多个值按指定格式拼接成字符串

C语言 sprintf()实现将多个值按指定格式拼接成字符串 举个例子 &#x1f330;&#xff1a;将字符串 “m” 与数字 0、1、2 动态拼接成 “m0”、“m1”、“m2”&#xff1a;&#x1f447;&#x1f3fb; #include <stdio.h> // 包含标准输入输出库&#xff0c;用于使用输入…

《Manus学习手册》.pdf(文末附完整版下载地址)

大家好&#xff0c;我是吾鳴。 吾鳴今天要给大家分享的一份比较全面详细的Manus学习手册&#xff0c;该学习手册主要包含Manus产品概述与核心理念、Manus功能与使用场景、Manus技术架构与工作流、Manus案例库与用户实践、邀请码获取与内测信息、Manus与传统AI对比与优势、用户评…

分治-快速排序系列一>快速排序

目录 题目方法&#xff1a;优化方法&#xff1a;代码&#xff1a; 题目方法&#xff1a; 忘记快速排序看这里&#xff1a;链接: link 优化方法&#xff1a; 代码&#xff1a; public int[] sortArray(int[] nums) {qsort(nums,0,nums.length-1);return nums;}private void qso…

Python模块化设计——递归

1.以下代码执行后,输出结果为____________。 def printDigit(n):print(n%10,end="")if(n>10

如何在百度搜索上删除与自己名字相关的资料

个人信息的网络足迹如同一张无形的网&#xff0c;将我们与世界的每一个角落紧密相连。然而&#xff0c;当某些与自己名字相关的资料不再希望被公众轻易检索到时&#xff0c;如何在百度搜索中有效“隐身”&#xff0c;成为了一个亟待解决的问题。面对复杂多变的网络环境&#xf…