基于贪心算法的一个决策问题
题目描述如下:
牛牛和妞妞从他们的好朋友小花那里各个拿了一个篮子,篮子里面装有同等数目的彩球,彩球上面有数字,他们都能看到自己以及对方篮子里面的彩球上面的数字,于是他们决定做个游戏,规则如下:
- 从对方篮子里面拿走一个球。
- 从自己篮子里拿出一个球累加到自己的总点数上。
只能从上面两种选择中取其一,也不能一个都不做,妞妞先开始,两个人交替做
牛牛和妞妞都很聪明
最后妞妞比牛牛总点数多多少?
思路如下:
- 牛牛和妞妞都很聪明,那他们肯定让自己多得分,对方少得分。
- 把两个篮子的彩球按照上面的数字大小降序排列
- 每次对比最大数字的那两个彩球,如果发现对方比自己的大,那就扔掉对方的
- 如果自己比对方大或者相等,那就把自己的那个加到自己的总点数上
- 基于数组下表操作即可
代码如下:(一 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
- 妞妞+9 妞妞剩余 8 8 7 3 牛牛剩余 9 9 7 6 4
牛牛+9 妞妞剩余 8 8 7 3 牛牛剩余 9 7 6 4 - 妞妞不变 妞妞剩余 8 8 7 3 牛牛剩余 7 6 4
牛牛不变 妞妞剩余 8 7 3 牛牛剩余 7 6 4 - 妞妞+8 妞妞剩余 7 3 牛牛剩余 7 6 4
牛牛+7 妞妞剩余 7 3 牛牛剩余 6 4 - 妞妞+7 妞妞剩余 3 牛牛剩余 6 4
牛牛+6 妞妞剩余 3 牛牛剩余 4 - 妞妞不变 妞妞剩余 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)。