面试算法 Dota2参议院 算法:贪心

1.题目:Dota2参议院
Dota2的世界里有两个阵营:Radiant(天辉)和Dire(夜魇)
Dota2参议院由来自两派的参议员组成。现在参议院希望对一个 Dota2游戏里的改变作出决定。他们以一个基于轮为过程的投票进行。在每一轮中,每一位参议员都可以行使两项权利中的一项:
禁止一名参议员的权利:参议员可以让另一位参议员在这一轮和随后的几轮中丧失所有的权利。宣布胜利:如果参议员发现有权利投票的参议员都是同一个阵营的,他可以宣布胜利并决定在游戏中的有关变化。
给定一个字符串代表每个参议员的阵营。字母“R”和“D”分别代表了Radiant(天辉)和Dire(夜魇)。然后,如果有n个参议员,给定字符串的大小将是no
以轮为基础的过程从给定顺序的第一个参议员开始到最后一个参议员结束。这一过程将持续到投票结束。所有失去权利的参议员将在过程中被跳过。
假设每一位参议员都足够聪明,会为自己的政党做出最好的策略,你需要预测哪一方最终会宣布胜利并在Dota2游戏中决定改变。输出应该是Radiant 或 Dire


2.算法:

贪心算法


3.算法思想:

贪心算法(greedy algorithm [8]  ,又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解  。

贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择。

贪心算法一般按如下步骤进行:  

①建立数学模型来描述问题   。

②把求解的问题分成若干个子问题   。

③对每个子问题求解,得到子问题的局部最优解 ] 。

④把子问题的解局部最优解合成原来解问题的一个解   。

贪心算法是一种对某些求最优解问题的更简单、更迅速的设计技术。贪心算法的特点是一步一步地进行,常以当前情况为基础根据某个优化测度作最优选择,而不考虑各种可能的整体情况,省去了为找最优解要穷尽所有可能而必须耗费的大量时间。贪心算法采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择,就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到问题的一个最优解。虽然每一步上都要保证能获得局部最优解,但由此产生的全局解有时不一定是最优的,所以贪心算法不要回溯。


4.代码:

/*************************************************
作者:She001
时间:2022/9/8
题目:Dota2参议院
Dota2的世界里有两个阵营:Radiant(天辉)和Dire(夜魇)
Dota2参议院由来自两派的参议员组成。现在参议院希望对一个 Dota2游戏里的改变作出决定。他们以一个基于轮为过程的投票进行。在每一轮中,每一位参议员都可以行使两项权利中的一项:
禁止一名参议员的权利:参议员可以让另一位参议员在这一轮和随后的几轮中丧失所有的权利。宣布胜利:如果参议员发现有权利投票的参议员都是同一个阵营的,他可以宣布胜利并决定在游戏中的有关变化。
给定一个字符串代表每个参议员的阵营。字母“R”和“D”分别代表了Radiant(天辉)和Dire(夜魇)。然后,如果有n个参议员,给定字符串的大小将是no
以轮为基础的过程从给定顺序的第一个参议员开始到最后一个参议员结束。这一过程将持续到投票结束。所有失去权利的参议员将在过程中被跳过。
假设每一位参议员都足够聪明,会为自己的政党做出最好的策略,你需要预测哪一方最终会宣布胜利并在Dota2游戏中决定改变。输出应该是Radiant 或 Dire



算法: 
2.贪心算法 
***************************************************/

#include<bits/stdc++.h>
using namespace std;

//贪心算法:
/*
1.首先我们要依据 数据的坐标来 一个一个的执行
2.利用贪心的思想,我们每个不同阵营的人 都会积极的除去 下一个离他最近得不同阵容得人   这样可以得到最大得利益
3.我们可以利用 队列来存储不同阵容得人, 先进先出, 活下去得人,继续添加到自己阵容得队列,
4.但是我们需要注意,我们第一轮得用户比完顺序得坐标 不能和之前相同,因为有其他的阵容第一轮还没有比, 其他阵容的对手可能在你比完之后删除你!! 
*/ 

char fangfa_1(char nn[])//nn  数组 
{
	queue<int> R;//队列先进先出 
	queue<int> D;
	int n=strlen(nn);
	for(int i=0;i<n;i++)
	{
		if(nn[i]=='R')
		{
			R.push(i);//入队 
		}
		if(nn[i]=='D')//判断是否为这个成员 
		{
			D.push(i);//入队, 
		}
	}
	//根据贪心的思想,我们要删除离自己最近的对手,
	//所以我们,可以每个 队列中同时推来 一个人,来对比成员的 下标大小,,下标小的 人可以把那个对手删除 ! 然后这个人进入下一轮!他的下标+ n  
	while(!R.empty()  && !D.empty())
	{
		int a=R.front();//返回第一个数据 
		R.pop();//出队 
		int b=D.front();//返回第一个数据 
		D.pop();
		
		if(a<b)
		{
			R.push(a+n);	
		}
		else
		{
			D.push(b+n);	
		} 
	}
	if(R.empty())//假如 R的队列是空的  返回  D 阵容赢了!  //empty()  是真的 返回  1  
	{
		return 'D';	
	}
	else//假如 D 的队列是空的  返回  R  阵容赢了!  
	{
		return 'R';	
	} 
}




int main()
{
	char num1[]="RRDDR";//数组 
	char num2[]="DDDRRRR";//数组
	char num3[]="RRD";// 
	char num4[]="DRRDR";
	char a=fangfa_1(num1);
	char a1=fangfa_1(num2);
	char a2=fangfa_1(num3);
	char a3=fangfa_1(num4);
	cout<<"a = "<<a<<endl;//输出 R 
	cout<<"a1 = "<<a1<<endl;//输出 D
	cout<<"a2 = "<<a2<<endl;//输出 R
	cout<<"a3 = "<<a3<<endl;//输出 R
	
	
	 
	 
	
	return 	0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值