第13章贪心算法

news/2025/3/15 4:32:28/

算法>贪心算法

局部最优求得总体最优

适用于桌上有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/news/1579226.html

相关文章

Yashan DB 实例管理

一、实例启停机制 1. 启动阶段 • NOMOUNT&#xff1a;启动实例&#xff0c;但不加载数据库。此状态下可以重建控制文件&#xff0c;例如控制文件损坏。启动到NOMOUNT状态的命令为yasboot cluster start -c yashandb -m nomount&#xff0c;此时查询V$INSTANCE视图的STATUS状…

基于Spring Boot的牙科诊所管理系统的设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

科技职场与文化的未来:2025年ISACA全球研究报告解读

1. 科技行业的性别多样性挑战与应对策略 根据ISACA的《科技职场与文化2025》全球研究报告&#xff0c;性别多样性仍然是科技行业面临的一个重要问题。尽管女性在解决科技技能危机中扮演着关键角色&#xff0c;但87%的受访者表示&#xff0c;性别差异仍然存在。报告指出&#x…

vue管理布局左侧菜单栏NavMenu

我们接着上回的写&#xff0c;我们写一下左侧的菜单 <el-aside style"width: 200px;"><divstyle"height: 60px;display: flex;align-items: center;justify-content: center;background-color: #ccc;color: white;">logo</div><el-m…

电路原理(电容 集成电路NE555)

电容 1.特性&#xff1a;充放电&#xff0c;隔直流&#xff0c;通交流 2.电容是通过聚集正负电荷来存储电能的 3.电容充放电过程可等效为导通回路 4.多电容并联可以把容量叠加&#xff0c;但是多电容串联就不会&#xff0c;只会叠加电容的耐压值。 6.电容充放电时相当于通路&a…

为什么 JPA 可以通过 findByNameContaining 自动生成 SQL 语句?

Spring Data JPA 的 方法名派生查询&#xff08;Query Derivation&#xff09; 是其核心特性之一&#xff0c;允许开发者通过简单的方法命名规则自动生成 SQL 查询&#xff0c;而无需手动编写 SQL 或 JPQL。以下是其实现原理和关键机制&#xff1a; 一、方法名解析规则 Spring…

[极客大挑战 2019]FinalSQL【SQL布尔盲注】

题目&#xff1a; 五个小框框什么也没有 发现应该在第六个框框有点线索&#xff0c;所以尝试url框里面id6试一试 表明flag 不在这个表里面。。。啥意思 用户名和密码处都试过了&#xff0c;过滤了很多&#xff0c;包括 ’ &#xff0c;select&#xff0c;databases&#xff…

【09】单片机编程核心技巧:变量赋值,从定义到存储的底层逻辑

【09】单片机编程核心技巧&#xff1a;变量赋值&#xff0c;从定义到存储的底层逻辑 &#x1f31f; 核心概念 单片机变量的定义与赋值是程序设计的基础&#xff0c;其本质是通过 RAM&#xff08;随机存储器&#xff09; 和 ROM&#xff08;只读存储器&#xff09; 的协作实现…