简单决策问题

本文介绍了一道基于贪心算法的决策问题,通过两个玩家轮流从彼此的有序彩球堆中选择最优策略来增加自身分数,最终计算两者的得分差距。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于贪心算法的一个决策问题

题目描述如下:

牛牛和妞妞从他们的好朋友小花那里各个拿了一个篮子,篮子里面装有同等数目的彩球,彩球上面有数字,他们都能看到自己以及对方篮子里面的彩球上面的数字,于是他们决定做个游戏,规则如下:

  1. 从对方篮子里面拿走一个球。
  2. 从自己篮子里拿出一个球累加到自己的总点数上。

只能从上面两种选择中取其一,也不能一个都不做,妞妞先开始,两个人交替做

牛牛和妞妞都很聪明

最后妞妞比牛牛总点数多多少?

思路如下:
  1. 牛牛和妞妞都很聪明,那他们肯定让自己多得分,对方少得分。
  2. 把两个篮子的彩球按照上面的数字大小降序排列
  3. 每次对比最大数字的那两个彩球,如果发现对方比自己的大,那就扔掉对方的
  4. 如果自己比对方大或者相等,那就把自己的那个加到自己的总点数上
  5. 基于数组下表操作即可
代码如下:(一 main到底)
#include<iostream>
#include<algorithm>
using namespace std;
int cmp(int a, int b)
{
 return a > b;
}
int main()
{
 int n;
 cin >> n;
 int *girl = new int[n];
 int *boy = new int[n];
 for (int i = 0; i < n; i++)
 {
  cin >> girl[i];
 }
 for (int i = 0; i < n; i++)
 {
  cin >> boy[i];
 }
 sort(girl, girl + n, cmp);
 sort(boy, boy + n, cmp);
 int tota_of_girl = 0;
 int total_of_boy = 0;
 int boundary = 0;          //边界条件
 int index_of_girl = 0;
 int index_of_boy = 0;
 while (boundary < n*2)
 {
  if (boundary % 2 == 0)
  {
    if (boy[index_of_boy] > girl[index_of_girl])
        index_of_boy++;
    else
   {
      tota_of_girl += girl[index_of_girl];
      index_of_girl++;
   }
  }
  else
  {
    if (boy[index_of_boy] < girl[index_of_girl])
      index_of_girl++;
    else
   {
       total_of_boy += boy[index_of_boy];
       index_of_boy++;
   }
  }
  boundary++;
 }
 delete[]girl;
 delete[]boy;
 cout << tota_of_girl - total_of_boy;
 return 0;
}

看一个例子
7 3 9 8 8
9 9 6 7 4

排序后

9 8 8 7 3
9 9 7 6 4

决策ing

  1. 妞妞+9 妞妞剩余 8 8 7 3 牛牛剩余 9 9 7 6 4
    牛牛+9 妞妞剩余 8 8 7 3 牛牛剩余 9 7 6 4
  2. 妞妞不变 妞妞剩余 8 8 7 3 牛牛剩余 7 6 4
    牛牛不变 妞妞剩余 8 7 3 牛牛剩余 7 6 4
  3. 妞妞+8 妞妞剩余 7 3 牛牛剩余 7 6 4
    牛牛+7 妞妞剩余 7 3 牛牛剩余 6 4
  4. 妞妞+7 妞妞剩余 3 牛牛剩余 6 4
    牛牛+6 妞妞剩余 3 牛牛剩余 4
  5. 妞妞不变 妞妞剩余 3 牛牛剩余0
    牛牛不变 妞妞剩余 0 牛牛剩余 0

总点数妞妞—牛牛:24-22=2

结果图

案例结果

代码有点乱 核心在这

while (boundary < n*2)
 {
  if (boundary % 2 == 0)
  {
   if (boy[index_of_boy] > girl[index_of_girl])
    index_of_boy++;
   else
   {
    tota_of_girl += girl[index_of_girl];
    index_of_girl++;
   }
  }
  else
  {
   if (boy[index_of_boy] < girl[index_of_girl])
    index_of_girl++;
   else
   {
    total_of_boy += boy[index_of_boy];
    index_of_boy++;
   }
  }
  boundary++;
 }

既用boundary作为边界条件,也用来对二取模判断是妞妞操作还是牛牛操作
不管是加上自己的还是拿走别人的 都用对数组下标+1来进行推进

代码中用了C++ STL封装的 sort函数进行排序,因为太懒了,这个sort是基于快排的,O(1)的空间,O(nlogn)的时间。

所以总体时间复杂度为O(nlogn)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值