【动态规划】对局匹配 (分组线性DP)

news2025/3/14 10:14:12

题目详情

问题描述:

        小明喜欢在一个围棋网站上找别人在线对弈。这个网站上所有注册用户都有一个积分,代表他的围棋水平。


  小明发现网站的自动对局系统在匹配对手时,只会将积分差恰好是K的两名用户匹配在一起。如果两人分差小于或大于K,系统都不会将他们匹配。


  现在小明知道这个网站总共有N名用户,以及他们的积分分别是A1, A2, ... AN。


  小明想了解最多可能有多少名用户同时在线寻找对手,但是系统却一场对局都匹配不起来(任意两名用户积分差不等于K)?

输入说明:

        第一行包含两个个整数N和K。
   第二行包含N个整数A1, A2, ... AN。


  对于20%的数据,1 <= N <= 10

        对于60%的数据,1 <= N <= 1000

  对于100%的数据,1 <= N <= 100000, 0 <= Ai <= 100000, 0 <= K <= 100000

测试用例:

输入:

10 0
1 4 2 8 5 7 1 4 2 8

输出:

6
 

题解

问题分析:

构建DP数组 DP[i]  i是积分的值 DP[i]代表前i个积分最多匹配不到的人数  

注意 当k等于0时 即为对局中积分不同的用户 需要特判

k不等0时 把积分分为K组 只有组内才有可能出现对局匹配 然后依次遍历每一组内 最大的DP[i] 每一组的max和即为ans  因为组内不能选择相邻的 组内积分按照k值递增   

DP数组初始化:

DP[val]数组初始化为有积分val的人数 因为k不等于0的话 那么起码积分相同的人不会匹配对局 没出现的积分全部初始化为0 所以DP数组在创建时就初始化为{0}

DP数组遍历方式:

外层遍历 组 i : 0~k-1 (分成k组 则每一组的起始分别从0~k-1开始)内层遍历组内每一个积分 j :i~Max j+=k (Max为所有玩家中的积分最大值 也是DP数组下标的上限)   

状态转移方程:

            if(j-2*k>=0){
                dp[j]=max(dp[j-k],dp[j-2*k]+cnt[j]);//要选j或者不选j
            }else if(j-k>=0){//j前面只有一个
                dp[j]=max(dp[j],dp[j-k]);
            }

题解代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#include<algorithm>
#include<set>
#include<sstream>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f
const int maxn=1e5+5;
int n,k;
int cnt[maxn]={0};//计数 初始化为0
int dp[maxn]={0};//dp[i]表示前i个积分 最多匹配不到的人数
int main(){
    cin>>n>>k;
    int val;
    int Max=-1;//记录最大的积分 方便后续遍历所有积分
    int sum=0;//统计不同数字的个数 方便k=0特判
    for(int i=1;i<=n;++i){
        cin>>val;
        cnt[val]++;//统计同一个数字有几个
        if(cnt[val]==1){
            sum++;//第一次碰到的数字 sum就++
        }
        dp[val]++;//dp初始化为val积分出现的个数
        Max=max(val,Max);//每次更新最大积分值
    }
    if(k==0){//k=0特判
        cout<<sum;
        return 0;
    }
    int ans=0;
    //分成k组 每一组的开头就是0~k-1 遍历每一组
    for(int i=0;i<k;++i){
        int j;//这样每次循环后会保存j的值
        for(j=i;j<=Max;j+=k){
            //分类讨论 如果j前面有两个
            if(j-2*k>=0){
                dp[j]=max(dp[j-k],dp[j-2*k]+cnt[j]);//要选j或者不选j
            }else if(j-k>=0){//j前面只有一个
                dp[j]=max(dp[j],dp[j-k]);
            }
        }
        ans+=dp[j-k];//j-k就是这一组里面最多匹配不到的人数 把每一组加在一起就可以了
    }
    cout<<ans;

    return 0;
}

Code具体说明:

数据结构与变量说明

  • n 和 k 分别表示用户的数量和积分差。
  • cnt[maxn] 用于记录每个积分值出现的次数。
  • dp[maxn] 动态规划数组,dp[i] 表示从积分0到积分i,最多有几个人无法找到对手进行匹配。
  • Max 记录所有输入积分中的最大值,用于后续遍历所有积分。
  • sum 统计不同积分的数量,用于处理k=0的特殊情况。

主要逻辑

  1. 输入处理

    • 首先读取用户数量n和积分差k
    • 然后循环读取每个用户的积分val,并更新cnt[val]以统计每个积分出现的次数。如果某个积分首次出现,则增加sum计数器。
    • 同时初始化dp[val]为该积分出现的次数,并更新Max为当前的最大积分。
  2. 特例处理 (k == 0)

    • 如果k为0,意味着没有两个用户可以匹配,因此直接输出不同积分的数量sum作为结果。
  3. 动态规划求解

    • 对于每个可能的起点i(从0到k-1),尝试将积分分成若干组,每组之间的积分差为k
    • 对于每一组,通过遍历所有可能的积分值j(从i开始,每次增加k),根据前面的状态来决定是否选择当前积分j
      • 如果j-2*k >= 0,则可以选择跳过前一组或两组,选取当前积分j或者不选。
      • 如果j-k >= 0,但j-2*k < 0,则只能考虑是否跳过前一组。
    • 更新ans,它累加了每一组中无法匹配的人数。
  4. 输出结果

    • 最终输出ans,即无法匹配的最多人数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2314801.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

247g 的工业级电调,如何让无人机飞得更 “聪明“?——STONE 200A-M 深度测评

一、轻量化设计背后的技术取舍 当拿到 STONE 200A-M 时&#xff0c;247g 的重量让人意外 —— 这个接近传统 200A 电调 70% 的重量&#xff0c;源自 1205624.5mm 的紧凑结构&#xff08;0.1mm 公差控制&#xff09;。实测装机显示&#xff0c;相比同规格产品&#xff0c;其体积…

Node.js:快速启动你的第一个Web服务器

Node.js 全面入门指南 文章目录 Node.js 全面入门指南一 安装Node.js1. Windows2. MacOS/Linux 二 配置开发环境1. VSCode集成 三 第一个Node.js程序1. 创建你的第一个Node.js程序 四 使用Express框架1. 快速搭建服务器 一 安装Node.js 1. Windows 以下是Windows环境下Node.j…

自定义日志回调函数实现第三方库日志集成:从理论到实战

一、应用场景与痛点分析 在开发过程中&#xff0c;我们经常会遇到以下场景&#xff1a; 日志格式统一&#xff1a;第三方库使用自己的日志格式&#xff0c;导致系统日志混杂&#xff0c;难以统一管理和分析。日志分级过滤&#xff1a;需要动态调整第三方库的日志输出级别&…

Linux练级宝典->任务管理和守护进程

任务管理 进程组概念 每个进程除了进程ID以外&#xff0c;还有一个进程组&#xff0c;进程组就是一个或多个进程的集合 同一个进程组&#xff0c;代表着他们是共同作业的&#xff0c;可以接收同一个终端的各种信号&#xff0c;进程组也有其唯一的进程组号。还有一个组长进程&a…

C语言:计算并输出三个整数的最大值 并对三个数排序

这是《C语言程序设计》73页的思考题。下面分享自己的思路和代码 思路&#xff1a; 代码&#xff1a; #include <stdio.h> int main() {int a,b,c,max,min,mid ; //设置大中小的数分别为max&#xff0c;mid&#xff0c;min&#xff0c;abc为输入的三个数printf("ple…

工具(十二):Java导出MySQL数据库表结构信息到excel

一、背景 遇到需求&#xff1a;将指定数据库表设计&#xff0c;统一导出到一个Excel中&#xff0c;存档查看。 如果一个一个弄&#xff0c;很复杂&#xff0c;耗时长。 二、写一个工具导出下 废话少絮&#xff0c;上码&#xff1a; 2.1 pom导入 <dependency><grou…

ACL初级总结

ACL–访问控制列表 1.访问控制 在路由器流量流入或者流出的接口上,匹配流量,然后执行相应动作 permit允许 deny拒绝 2.抓取感兴趣流 3.ACL匹配规则 自上而下逐一匹配,若匹配到了则按照对应规则执行动作,而不再向下继续匹配 思科:ACL列表末尾隐含一条拒绝所有的规则 华为:AC…

调优案例一:堆空间扩容提升吞吐量实战记录

&#x1f4dd; 调优案例一&#xff1a;堆空间扩容提升吞吐量实战记录 &#x1f527; 调优策略&#xff1a;堆空间扩容三部曲 # 原配置&#xff08;30MB堆空间&#xff09; export CATALINA_OPTS"$CATALINA_OPTS -Xms30m -Xmx30m"# 新配置&#xff08;扩容至120MB&am…

C语言 —— 此去经年梦浪荡魂音 - 深入理解指针(卷一)

目录 1. 内存和地址 2. 指针变量和地址 2.1 取地址操作符&#xff08;&&#xff09; 2.2 指针变量 2.3 解引用操作符 &#xff08;*&#xff09; 3. 指针的解引用 3.1 指针 - 整数 3.2 void* 指针 4. const修饰指针 4.1 const修饰变量 4.2 const修饰指针变量 5…

计算机毕业设计:留守儿童的可视化界面

留守儿童的可视化界面mysql数据库创建语句留守儿童的可视化界面oracle数据库创建语句留守儿童的可视化界面sqlserver数据库创建语句留守儿童的可视化界面springspringMVChibernate框架对象(javaBean,pojo)设计留守儿童的可视化界面springspringMVCmybatis框架对象(javaBean,poj…

golang算法二叉树对称平衡右视图

100. 相同的树 给你两棵二叉树的根节点 p 和 q &#xff0c;编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是相同的。 示例 1&#xff1a; 输入&#xff1a;p [1,2,3], q [1,2,3] 输出&#xff1a…

Chatbox通过百炼调用DeepSeek

解决方案链接&#xff1a;评测&#xff5c;零门槛&#xff0c;即刻拥有DeepSeek-R1满血版 方案概览 本方案以 DeepSeek-R1 满血版为例进行演示&#xff0c;通过百炼模型服务进行 DeepSeek 开源模型调用&#xff0c;可以根据实际需求选择其他参数规模的 DeepSeek 模型。百炼平台…

【数据结构】6栈

0 章节 3&#xff0e;1到3&#xff0e;3小节。 认知与理解栈结构&#xff1b; 列举栈的操作特点。 理解并列举栈的应用案例。 重点 栈的特点与实现&#xff1b; 难点 栈的灵活实现与应用 作业或思考题 完成学习测试&#xff12;&#xff0c;&#xff1f; 内容达成以下标准(考核…

PyTorch 入门学习

目录 PyTorch 定义 核心作用 应用场景 Pytorch 基本语法 1. 张量的创建 2. 张量的类型转换 3. 张量数值计算 4. 张量运算函数 5. 张量索引操作 6. 张量形状操作 7. 张量拼接操作 8. 自动微分模块 9. 案例-线性回归案例 PyTorch 定义 PyTorch 是一个基于 Python 深…

mov格式视频如何转换mp4?

mov格式视频如何转换mp4&#xff1f;在日常的视频处理中&#xff0c;经常需要将MOV格式的视频转换为MP4格式&#xff0c;以兼容更多的播放设备和平台。下面给大家分享如何将MOV视频转换为MP4&#xff0c;4款视频格式转换工具分享。 一、牛学长转码大师 牛学长转码大师是一款功…

二进制求和(js实现,LeetCode:67)

这道题我的解决思路是先将a和b的长度保持一致以方便后续按位加减 let lena a.length let lenb b.length if (lena ! lenb) {if (lena > lenb) {for (let i 0; i <lena-lenb; i) {b 0 b}} else {for (let i 0; i < lenb-lena; i) {a 0 a}} } 下一步直接进行按…

【C#】使用DeepSeek帮助评估数据库性能问题,C# 使用定时任务,每隔一分钟移除一次表,再重新创建表,和往新创建的表追加5万多条记录

&#x1f339;欢迎来到《小5讲堂》&#x1f339; &#x1f339;这是《C#》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。&#x1f339; &#x1f339;温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01;&#…

【openGauss】物理备份恢复

文章目录 1. gs_backup&#xff08;1&#xff09;备份&#xff08;2&#xff09;恢复&#xff08;3&#xff09;手动恢复的办法 2. gs_basebackup&#xff08;1&#xff09;备份&#xff08;2&#xff09;恢复① 伪造数据目录丢失② 恢复 3. gs_probackup&#xff08;1&#xf…

蓝桥杯备赛-基础练习 day1

1、闰年判断 问题描述 给定一个年份&#xff0c;判断这一年是不是闰年。 当以下情况之一满足时&#xff0c;这一年是闰年:1.年份是4的倍数而不是100的倍数 2&#xff0e;年份是400的倍数。 其他的年份都不是闰年。 输入格式 输入包含一个…

实验四 Python聚类决策树训练与预测 基于神经网络的MNIST手写体识别

一、实验目的 Python聚类决策树训练与预测&#xff1a; 1、掌握决策树的基本原理并理解监督学习的基本思想。 2、掌握Python实现决策树的方法。 基于神经网络的MNIST手写体识别&#xff1a; 1、学习导入和使用Tensorflow。 2、理解学习神经网络的基本原理。 3、学习使用…