蓝桥杯——对局匹配

文章讲述了如何使用动态规划、暴力枚举和记忆化搜索的方法解决最长递增子序列问题,以及在一个用户积分匹配场景中,如何通过两种方法找到最多无法匹配的用户数。
摘要由CSDN通过智能技术生成

目录

动态规划:

暴力枚举(暴力搜索)

代码实现

记忆化搜索(通过哈希表或字典保存结果)——递归树的剪枝

非递归、迭代算法

​编辑

 题目理解:

第一种方法

分析:

难点:考虑到k=0的情况

思路:

代码:

第二种方法

思路:

注意:


动态规划:

nums=【1,5,2,4,3】找出最长的递增的子序列

eg.1 、2、 3或者1、 2、 4

找出最长的递增的子序列的长度:

暴力枚举(暴力搜索)

eg.

     从1出发,可以选择5、 2、 4 、3

假如第二个数字选5,则其他的无法选择,最长长度为2

假如第二个数字选2,则可以选择3、 4,最长长度为3

……

直到子序列遍历完,并且需要实时记录当前最长的子序列长度

代码实现

时间复杂度:假设数组的个数为n,则存在2^n个子序列,每个子序列都要遍历一遍即

             O(n*2^n) 

记忆化搜索(通过哈希表或字典保存结果)——递归树的剪枝

非递归、迭代算法

 题目理解:

示例中表示有10个用户,其中有两个1,两个4,两个2,两个8,一个5,一个7

当系统在一场对局中匹配不起来时,即1、4、2、8、5、7在线,另外的1、4、2、8不在线时,此时最多有6名用户无法匹配

第一种方法

分析:

①当k的值不等于0时,总人数-可以匹配的人就是最多无法匹配的情况

eg.k=4 ,用户积分为1,2,3,3,4,5,6

可匹配:(1,5)(2,6)

则保留1、2或者5 、6

7-2=5……最多5人无法匹配

②当k的值等于0时,且此时能匹配的人数>=3,总人数-积分相同的人数+相同的数字数量

eg.k=0, 用户积分为11115

5-4+1=2……最多两人

难点:考虑到k=0的情况

思路:

代码:

运行超时了……

​#include <iostream>
using namespace std;

// 存储一个大数用来表示用户人数的存储空间
const int MAX=100000;
int count[MAX];

int main()
{
  int n,k,maxn=0;
  // n代表用户人数,k代表相差k个积分匹配,maxn最大积分
  cin>>n>>k;
  // for循环遍历所有数组
  for(int i=0;i<n;i++)
  {
    int temp;
    cin>>temp;
    count[temp]++;
    maxn=maxn>temp?maxn:temp;
  }
  int match=0;
  for(int i=0;i+k<=maxn;i++)
  {
    while(k&&count[i]&&count[i+k])
    {
      match++;
      count[i]--;
      count[i+k]--;
    }
    while(!k&&count[i]>=2)
    {
      match+=count[i]-1;
      count[i]=1;

    }
  }
  cout << n-match << endl;
  return 0;
}

第二种方法

思路:(动态规划)

①确定dp数组的定义:

dp[i] 表示选择前i个积分能获得的最大用户人数

②递推公式

题目理解:

eg. 

     n=10   k=1

示例:2 1 1 1 1 4 4 3 4 4

dp[0]=5

dp[1]=9

dp[2]=9

dp[3]=9

注意:

main函数需要返回0

放弃一下,明天再看

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值