当前位置: 首页 > news >正文

maui 调用文心一言开发的聊天APP 3

主要是对代码进行了优化

  1. 上一个版本写死了帐号跟密码 ,这一个帐本有户可以直接设置
  2. 对相关的key以及secret如果设置错时,在聊天中也会返回提示。
  3. 注册帐号时同时也设置了key及secrete
  4. 升级到了net.8.0
  5. 导出APK,上一个版本是导出abb.
  6. 解决了变型问题,现在生成桌面系统也能正常显示。

注册界面

在这里插入图片描述

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"x:Class="AiChat.Views.RegPage"Shell.NavBarIsVisible="True"xmlns:mct="clr-namespace:CommunityToolkit.Maui.Behaviors;assembly=CommunityToolkit.Maui"xmlns:local="clr-namespace:AiChat.Views;assembly=AiChat"Title="注册"><Grid RowDefinitions="Auto,*" Margin="0,10,0,0"><VerticalStackLayout Padding="10" VerticalOptions="Center" HorizontalOptions="FillAndExpand"><Frame BorderColor="White"CornerRadius="10"HasShadow="True"Margin="0,20,0,0"ZIndex="0"Padding="8"><Frame.Shadow><Shadow Brush="Black"Offset="20,20"Radius="10"Opacity="0.9" /></Frame.Shadow><StackLayout Padding="10"><VerticalStackLayout Padding="10" BackgroundColor="{StaticResource White}"><Label Text="AI CHAT"FontSize="30"FontAttributes="Bold"TextColor="{StaticResource Cyan100Accent}"FontFamily="Consolas"Padding="5"/><Label Text="to continue!" TextColor="{StaticResource Cyan100Accent}"FontSize="14" Padding="5"FontAttributes="Bold" /></VerticalStackLayout><VerticalStackLayout Padding="10"><Label FontFamily="Consolas" Text="手机号" TextColor="{StaticResource Cyan100Accent}" /><Frame CornerRadius="10" Padding="3" Margin="0,10,0,0"><VerticalStackLayout><Entry x:Name="Phone" Text="{Binding Phone,Mode=TwoWay}" Margin="5,0,0,0" Placeholder="手机" FontSize="14"><Entry.Behaviors><local:PhoneNumberValidatorBehavior /></Entry.Behaviors></Entry></VerticalStackLayout></Frame><VerticalStackLayout Padding="0" Margin="0,5,0,0"><Label FontFamily="Consolas" Text="密码" TextColor="{StaticResource Cyan100Accent}"  /><Frame CornerRadius="10" Padding="3" Margin="0,10,0,0"><Entry x:Name="Password" Text="{Binding Password,Mode=TwoWay}" Margin="5,0,0,0" Placeholder="密码6位数字" IsPassword="True" FontSize="14"><Entry.Behaviors><local:PasswordValidatorBehavior /></Entry.Behaviors></Entry></Frame></VerticalStackLayout><Label FontFamily="Consolas" Text="文心一言API_KEY" TextColor="{StaticResource Cyan100Accent}" /><Frame CornerRadius="10" Padding="3" Margin="0,10,0,0"><VerticalStackLayout><Entry x:Name="API_KEY" Text="{Binding API_KEY,Mode=TwoWay}" Margin="5,0,0,0" Placeholder="API_KEY" FontSize="14" /></VerticalStackLayout></Frame><Label FontFamily="Consolas" Text="文心一言SECRET_KEY" TextColor="{StaticResource Cyan100Accent}" /><Frame CornerRadius="10" Padding="3" Margin="0,10,0,0"><VerticalStackLayout><Entry x:Name="SECRET_KEY" Text="{Binding SECRET_KEY,Mode=TwoWay}" Margin="5,0,0,0" Placeholder="SECRET_KEY" FontSize="14" /></VerticalStackLayout></Frame><Button Margin="0,20,0,0"x:Name="RegButton"Clicked="RegButton_Clicked"Text="确定注册" VerticalOptions="CenterAndExpand" BackgroundColor="{StaticResource Cyan100Accent}" HorizontalOptions="FillAndExpand"/><BoxView Color="{StaticResource Cyan100Accent}"Margin="0,20,0,0"HeightRequest="2"HorizontalOptions="Fill" /><Grid Padding="10" Margin="0,10,0,0" InputTransparent="False"><Label FontFamily="Consolas"  InputTransparent="False"><Label.FormattedText><FormattedString><Span Text="返回 " TextColor="{StaticResource Cyan100Accent}" /><Span Text="登陆" TextColor="{StaticResource Cyan100Accent}" /></FormattedString></Label.FormattedText><Label.GestureRecognizers><TapGestureRecognizer Tapped="OnLoginLabelTapped" /></Label.GestureRecognizers></Label></Grid><Grid Padding="10" Margin="0,10,0,0" InputTransparent="False"><Label FontFamily="Consolas"  InputTransparent="False"><Label.FormattedText><FormattedString><Span Text="百度文言一心登陆获取 API_KEY SECRET_KEY" TextColor="Red" /></FormattedString></Label.FormattedText><Label.GestureRecognizers><TapGestureRecognizer Tapped="OnBaiduLabelTapped" /></Label.GestureRecognizers></Label></Grid></VerticalStackLayout></StackLayout></Frame></VerticalStackLayout></Grid>
</ContentPage>

using System.Text.RegularExpressions;
using System.Windows.Input;
using static Microsoft.Maui.ApplicationModel.Permissions;
namespace AiChat.Views
{public class PhoneNumberValidatorBehavior : Behavior<Entry>{protected override void OnAttachedTo(Entry entry){entry.TextChanged += OnEntryTextChanged;base.OnAttachedTo(entry);}protected override void OnDetachingFrom(Entry entry){entry.TextChanged -= OnEntryTextChanged;base.OnDetachingFrom(entry);}private void OnEntryTextChanged(object sender, TextChangedEventArgs args){if (!(sender is Entry entry))return;string phoneNumber = args.NewTextValue;bool isValid = Regex.IsMatch(phoneNumber, @"^\d{11}$");// Set IsValid property on the associated entryentry.SetValue(IsValidProperty, isValid);}public static readonly BindableProperty IsValidProperty =BindableProperty.CreateAttached("IsValid", typeof(bool), typeof(PhoneNumberValidatorBehavior), false);}public class PasswordValidatorBehavior : Behavior<Entry>{protected override void OnAttachedTo(Entry entry){entry.TextChanged += OnEntryTextChanged;base.OnAttachedTo(entry);}protected override void OnDetachingFrom(Entry entry){entry.TextChanged -= OnEntryTextChanged;base.OnDetachingFrom(entry);}private void OnEntryTextChanged(object sender, TextChangedEventArgs args){if (!(sender is Entry entry))return;string password = args.NewTextValue;bool isValid = Regex.IsMatch(password, @"^\d{6}$");// Set IsValid property on the associated entryentry.SetValue(IsValidProperty, isValid);}public static readonly BindableProperty IsValidProperty =BindableProperty.CreateAttached("IsValid", typeof(bool), typeof(PasswordValidatorBehavior), false);}public partial class RegPage : ContentPage{public RegPage(){InitializeComponent();BindingContext = this;}private async void OnLoginLabelTapped(object sender, EventArgs e){var nextPage = new LoginPage();var navigation = Application.Current.MainPage.Navigation;await navigation.PushAsync(nextPage);}private async void OnBaiduLabelTapped(object sender, EventArgs e){await Launcher.TryOpenAsync(new Uri("https://login.bce.baidu.com/"));}protected override bool OnBackButtonPressed(){Application.Current.Quit();return true;}private async void RegButton_Clicked(object sender, EventArgs e){bool isPhoneValid = (bool)Phone.GetValue(PhoneNumberValidatorBehavior.IsValidProperty);bool isPasswordValid = (bool)Password.GetValue(PasswordValidatorBehavior.IsValidProperty);if (isPhoneValid && isPasswordValid){if (string.IsNullOrEmpty(API_KEY.Text) || string.IsNullOrEmpty(SECRET_KEY.Text)){await DisplayAlert("确定", "API_KEY  SECRET_KEY 不能为空?", "确定"); // 修改按钮标签为 "确定"return;}if (await DisplayAlert("确定", "确定增加吗?", "确定", "取消")) // 修改按钮标签为 "确定" 和 "取消"{await SecureStorage.SetAsync("PHONE", Phone.Text);await SecureStorage.SetAsync("PASSWORD", Password.Text);await SecureStorage.SetAsync("API_KEY", API_KEY.Text);await SecureStorage.SetAsync("SECRET_KEY", SECRET_KEY.Text);await DisplayAlert("成功", "注册成功", "OK");}}else{await DisplayAlert("验证失改", "手机号密码错", "OK");}}}
}

加入了手机号密码的验证,同时要求加入API_KEY,SECRET_KEY。

聊天代码

using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace AiChat.Views
{// 用于将文本颜色转换为视图颜色的转换器public class MessageColorConverter : IValueConverter{public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture){// 根据“IsUser”的值确定文本颜色的逻辑bool isUser = (bool)value;if (isUser){// 返回用户的文本颜色return Color.FromHex("#0000FF"); // 更改为所需的颜色}else{// 返回其他情况的文本颜色return Color.FromHex("#000000");// 更改为所需的颜色}}public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture){// 如果需要双向绑定,请实现此方法进行转换throw new NotImplementedException();}}// 聊天页面类public partial class Chat : ContentPage{// 定义表示聊天消息的类public class ChatMessage{public string Text { get; set; }public bool IsUser { get; set; }public DateTime Timestamp { get; set; }}static string sAPI_KEY = "";static string sSECRET_KEY = "";// 用于存储聊天消息的集合private ObservableCollection<ChatMessage> chatMessages = new ObservableCollection<ChatMessage>();// 构造函数public Chat(){InitializeComponent();// 将chatMessages集合绑定到CollectionView的ItemsSourcecollectionView.ItemsSource = chatMessages;SetStoredValues();}// 获取 API_KEY SECRET_KEYprivate async void SetStoredValues(){var storedKey = await SecureStorage.GetAsync("API_KEY");if (!string.IsNullOrEmpty(storedKey)){sAPI_KEY = storedKey;}var storedSecret = await SecureStorage.GetAsync("SECRET_KEY");if (!string.IsNullOrEmpty(storedSecret)){sSECRET_KEY = storedSecret;}entryUserMessage.Text = "";}// 发送消息按钮点击事件处理程序private async void SendMessage_Clicked(object sender, EventArgs e){try{sendmessageButton.IsEnabled = false;loadingIndicator.IsVisible = true;// 从Entry中获取用户的消息string userMessage = entryUserMessage.Text;if (string.IsNullOrEmpty(userMessage) ){ return;   }// 将用户的消息添加到chatMessages集合,并添加时间戳chatMessages.Add(new ChatMessage{Text = $"您:{userMessage}",IsUser = true,Timestamp = DateTime.Now});// 模拟对方的响应string response = await getAnswer(userMessage);response = response != null ? response : "请配置好文心一言的API_KEY SECRET_KEY";// 将对方的响应添加到chatMessages集合,并添加时间戳chatMessages.Add(new ChatMessage{Text = $"AI:{response}",IsUser = false,Timestamp = DateTime.Now}); // 可选:滚动到底部以显示最新的消息collectionView.ScrollTo(chatMessages[chatMessages.Count - 1], ScrollToPosition.End);// 发送后清除用户的输入entryUserMessage.Text = string.Empty;}finally{// Hide the loading indicator when the operation is completeloadingIndicator.IsVisible = false;sendmessageButton.IsEnabled = true;}}public static async Task<string> getAnswer(string question){var url = $"https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/aquilachat_7b?access_token={await GetAccessToken()}";var payload = JsonConvert.SerializeObject(new{messages = new[]{new { role = "user", content = question }}});using (var client = new HttpClient()){var content = new StringContent(payload, Encoding.UTF8, "application/json");var response = await client.PostAsync(url, content);if (response.IsSuccessStatusCode){var responseContent = await response.Content.ReadAsStringAsync();var dictObj = JsonConvert.DeserializeObject<dynamic>(responseContent);return dictObj.result;}else{Console.WriteLine($"HTTP请求失败: {response.StatusCode}");return "请配置好文心一言的API_KEY SECRET_KEY";}}}private static async Task<string> GetAccessToken(){var url = "https://aip.baidubce.com/oauth/2.0/token";using (var client = new HttpClient()){var parameters = new FormUrlEncodedContent(new[]{new KeyValuePair<string, string>("grant_type", "client_credentials"),new KeyValuePair<string, string>("client_id", sAPI_KEY),new KeyValuePair<string, string>("client_secret", sSECRET_KEY)});var response = await client.PostAsync(url, parameters);if (response.IsSuccessStatusCode){var content = await response.Content.ReadAsStringAsync();var result = JsonConvert.DeserializeObject<dynamic>(content);return result.access_token;}else{Console.WriteLine($"HTTP请求失败: {response.StatusCode}");return "wrong";}}}}
}

桌面界面:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

相关文章:

maui 调用文心一言开发的聊天APP 3

主要是对代码进行了优化 上一个版本写死了帐号跟密码 &#xff0c;这一个帐本有户可以直接设置对相关的key以及secret如果设置错时&#xff0c;在聊天中也会返回提示。注册帐号时同时也设置了key及secrete升级到了net.8.0导出APK&#xff0c;上一个版本是导出abb.解决了变型问…...

鸿蒙开发 - ohpm安装第三方库

前端开发难免使用第三方库&#xff0c;鸿蒙亦是如此&#xff0c;在使用 DevEco Studio 开发工具时&#xff0c;如何引入第三方库呢&#xff1f;操作步骤如下&#xff0c;假设你使用的是MacOS&#xff0c;假设你已经创建了了一个项目&#xff1a; 一、配置 HTTP Proxy 在打开了…...

[C++] new和delete

使用new时调用构造函数使用delete时调用析构函数 构造函数 使用new动态分配内存时&#xff0c;如果分配的是基本类型的内存&#xff0c;则不会调用构造函数。如果分配的是自定义类型的内存&#xff0c;则会调用构造函数进行对象的初始化。 例如&#xff1a; int* pInt new…...

OpenVINS学习2——VIRAL数据集eee01.bag运行

前言 周末休息了两天&#xff0c;接着做上周五那个VIRAL数据集没有运行成功的工作。现在的最新OpenVINS需要重新写配置文件&#xff0c;不像之前那样都写在launch里&#xff0c;因此需要根据数据集情况配置好estimator_config.yaml还有两个标定参数文件。 VIRAL数据集 VIRAL…...

jemeter,断言:响应断言、Json断言

一、响应断言 接口A请求正常返回值如下&#xff1a; {"status": 10013, "message": "user sign timeout"} 在该接口下创建【响应断言】元件&#xff0c;配置如下&#xff1a; 若断言成功&#xff0c;则查看结果树的接口显示绿色&#xff0c;若…...

【vue实战项目】通用管理系统:信息列表,信息的编辑和删除

本文为博主的vue实战小项目系列中的第七篇&#xff0c;很适合后端或者才入门的小伙伴看&#xff0c;一个前端项目从0到1的保姆级教学。前面的内容&#xff1a; 【vue实战项目】通用管理系统&#xff1a;登录页-CSDN博客 【vue实战项目】通用管理系统&#xff1a;封装token操作…...

基于FPGA的视频接口之高速IO(光纤)

简介 对于高速IO口配置光纤,现在目前大部分开发板都有配置,且也有说明,在此根据自己的工作经验以及对于各开发板的说明归纳 通过高速IO接口,以及硬件配置,可以实现对于光纤的收发功能,由于GTX的速率在500Mbs到10Gbps之间,但通道高速io可配置光纤10G硬件,物理通完成,则…...

HTML实现页面

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>工商银行电子汇款单</title> </head> &…...

回归预测 | MATLAB实现IWOA-LSTM改进鲸鱼算法算法优化长短期记忆神经网络的数据回归预测(多指标,多图)

回归预测 | MATLAB实现IWOA-LSTM改进鲸鱼算法算法优化长短期记忆神经网络的数据回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现IWOA-LSTM改进鲸鱼算法算法优化长短期记忆神经网络的数据回归预测&#xff08;多指标&#xff0c;多图&#…...

鸿蒙开发之状态管理@State

1、视图数据双向绑定 鸿蒙开发采用的声明式UI&#xff0c;利用状态驱动UI的更新。其中State被称作装饰器&#xff0c;是一种状态管理的方式。 状态&#xff1a;指的是被装饰器装饰的驱动视图更新的数据。 视图&#xff1a;是指用户看到的UI渲染出来的界面。 之所以成为双向…...

redis基本用法学习(主要数据类型)

redis官网教程中介绍有三种方式连接redis&#xff1a;命令行、gui工具和编程连接&#xff1a;   命令行方式主要是在命令行中输入redis-cli后&#xff0c;通过命令方式与redis服务进行交互&#xff0c;支持两种模式&#xff1a;REPL模式&#xff08;简单的交互式的编程环境&a…...

低代码:美味膳食或垃圾食品

低代码开发是近年来迅速崛起的软件开发方法&#xff0c;让编写应用程序变得更快、更简单。有人说它是美味的膳食&#xff0c;让开发过程高效而满足&#xff0c;但也有人质疑它是垃圾食品&#xff0c;缺乏定制性与深度。你认为低代码到底是美味的膳食还是垃圾食品呢&#xff0c;…...

设计模式—观察者模式

观察者模式&#xff08;Observer Pattern&#xff09;是一种行为型设计模式&#xff0c;它定义了一种一对多的依赖关系&#xff0c;使得当一个对象的状态发生变化时&#xff0c;所有依赖于它的对象都会得到通知并自动更新。 在观察者模式中&#xff0c;有两个核心角色&#xf…...

Java_EasyExcel_导入_导出Java-js

easyExcel导入 从easyexcel官网中拷贝过来&#xff0c;使用到的&#xff0c;这是使用监听器的方法。 EasyExcel.read(file.getInputStream(), BaseStoreDataExcelVo.class, new ReadListener<BaseStoreDataExcelVo>() {/*** 单次缓存的数据量*/public static final int…...

循环神经网络-RNN记忆能力实验 [HBU]

目录 一、循环神经网络 二、循环神经网络的记忆能力实验 三、数据集构建 数据集的构建函数 加载数据并进行数据划分 构造Dataset类 四、模型构建 嵌入层 SRN层 五、模型训练 训练指定长度的数字预测模型 多组训练 损失曲线展示 六、模型评价 参考《神经网络与深度…...

P1044 [NOIP2003 普及组] 栈——卡特兰数

传送门&#xff1a; P1044 [NOIP2003 普及组] 栈 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1044 公式一&#xff1a;递推式(注意开 long long &#xff0c;然后 先乘完再除&#xff0c;防止下取整&#xff09; typedef long long ll;…...

9:00面试,9:06就出来了,问的问题有点变态。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到12月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40…...

ets:tab2list的不足之处与替代方法,以及gen_server中使用ets的优缺点

ets:tab2list 是 Erlang/OTP 中的一个函数&#xff0c;用于将 ETS&#xff08;Erlang Term Storage&#xff09;表转换为列表。ETS 是 Erlang 中的一个内建数据库&#xff0c;允许开发者在内存中存储大量数据。 一、ets:tab2list 的不足之处&#xff1a; 性能问题&#xff1a;…...

软件测试之压力测试详解

一、什么是压力测试 软件测试中&#xff1a;压力测试&#xff08;Stress Test&#xff09;&#xff0c;也称为强度测试、负载测试。压力测试是模拟实际应用的软硬件环境及用户使用过程的系统负荷&#xff0c;长时间或超大负荷地运行测试软件&#xff0c;来测试被测系统的性能、…...

SpringBoot之请求的详细解析

1. 请求 在本章节呢&#xff0c;我们主要讲解&#xff0c;如何接收页面传递过来的请求数据。 1.1 Postman 之前我们课程中有提到当前最为主流的开发模式&#xff1a;前后端分离 在这种模式下&#xff0c;前端技术人员基于"接口文档"&#xff0c;开发前端程序&…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)

在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...

倒装芯片凸点成型工艺

UBM&#xff08;Under Bump Metallization&#xff09;与Bump&#xff08;焊球&#xff09;形成工艺流程。我们可以将整张流程图分为三大阶段来理解&#xff1a; &#x1f527; 一、UBM&#xff08;Under Bump Metallization&#xff09;工艺流程&#xff08;黄色区域&#xff…...

负载均衡器》》LVS、Nginx、HAproxy 区别

虚拟主机 先4&#xff0c;后7...

背包问题双雄:01 背包与完全背包详解(Java 实现)

一、背包问题概述 背包问题是动态规划领域的经典问题&#xff0c;其核心在于如何在有限容量的背包中选择物品&#xff0c;使得总价值最大化。根据物品选择规则的不同&#xff0c;主要分为两类&#xff1a; 01 背包&#xff1a;每件物品最多选 1 次&#xff08;选或不选&#…...