贪心算法-OJ例题

@贪心算法–OJ Accepted

区间覆盖

题目描述:
给出n个区间的起点和终点,求最少使用其中多少个区间可以将所有区间所在的区域完全覆盖。

输入:第一行输入一个整数n,表示n个区间;
第二行开始输入n行,每行两个整数,表示一个区间范围

输出:满足条件的区间

贪心算法体现:
最优子选择:每次记录的区间都为满足条件下范围最大(即最优)的区间
贪心选择:每次选择的区间覆盖范围最大

【Accepted】 OJ代码

#include
#include
#include
using namespace std;
int n;
struct a
{
     	int x, y;
}aa[1000];
void sort()   //升序,先按照x大小,相等时按照y大小
{
	for (int i = 0; i < n-1; i++)
		for (int j = i + 1; j < n; j++)
			if (aa[i].x > aa[j].x)  //按照x升序
			{
				a b = aa[i];  //交换
				aa[i] = aa[j];
				aa[j] = b;
			}
			else if (aa[i].x == aa[j].x)  //x相等时按照y大小升序
			{
				if (aa[i].y > aa[j].y)
				{
					a b = aa[i];
					aa[i] = aa[j];
					aa[j] = b;
				}
			}
}
int main() 
{
	cin >> n;
	for (int i = 0; i < n; i++)
			cin >> aa[i].x>>aa[i].y;
	bool flag = false;  //标志位,标志区间是否产生变动
	int  mx = 1, my = 0;; //临时变量,记录左右坐标
	int t = 1, i=0;
	sort();
	for (i = 0; i < n; i++)
		if (aa[i].x == 1 && aa[i].y > my)  //找到左区间为1的最大范围起始位置
		{
			my = aa[i].y;
			t = i;
		}
	i = t;  //从最大范围起始位置之后开始搜索
	cout << mx << ' ' << my << endl;  //输出最大范围的起始位置
	while (i <n)
	{	
		flag = false;
		for (int j = i+1; j < n; j++)  //循环寻找
		{
			if ((aa[i].y >= aa[j].x || aa[i].y + 1 == aa[j].x))  //满足条件的区间
			// aa[i].y + 1 == aa[j].x表示如[1,4][5,6]问题
				if (aa[j].y > my)   //如果可以到达的范围更远,即右区间更大
				{
					my = aa[j].y;
					mx = aa[j].x;
					flag = true;   //记录区间已变化
					t = j-1;  //i从当前位置进行比较
				}
		}
		if (flag == true)
		{	
			i = t;
			cout << mx << ' ' << my << endl;  //输出
		}	
		i++;
	}
	system("pause");
	return 0;
}

运行截图:
贪心算法-OJ例题_第1张图片
PS:搜索最优区间时用for+if,千万千万不要只用while(条件) 判断,否则会搞不清本题例子的输出逻辑。

小伟玩游戏

题目描述:
小伟报名参加中央电视台的智力大冲浪节目,本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者m元。先不要太高兴!因为这些钱还不一定都是你的!接下来主持人宣布了比赛规则:
首先,比赛时间分为n个时段(n≤500),它又给出了很多小游戏,每个小游戏都必须在规定期限ti前完成(1≤ti≤n)。如果一个游戏没能在规定期限前完成,则要从奖励费m元中扣去一部分钱wi,wi为自然数,不同的游戏扣去的钱是不一样的。当然,每个游戏本身都很简单,保证每个参赛者都能在一个时段内完成,而且都必须从整时段开始。主持人只是想考考每个参赛者如何安排组织自己做游戏的顺序。作为参赛者,小伟很想赢得冠军,当然更想赢取最多的钱!注意:比赛绝对不会让参赛者赔钱!

【Accepted】 OJ代码

#include
using namespace std;
int m,n, a[1000],c[1000];
void sort()   //根据扣除的钱排序
{
	for(int i=0;i<n;i++)
		for(int j=i+1;j<n;j++)
			if (a[i] > a[j])
			{
				int b = a[i];
				a[i]= a[j];
				a[j] = b;
				b = c[i];
				c[i] = c[j];
				c[j] = b;
			}
}
int main() 
{
	int b[1000];
	bool flag = false;
	cin >> m >> n;
	for (int i = 0; i < n; i++)
	{
		b[i] = 0;
		cin >> c[i];  //记录位置
	}
	for (int i = 0; i < n; i++)
		cin >> a[i];   //记录金钱
	sort();
	for (int i = n - 1; i >= 0; i--)
	{
		flag = false;
		for (int j = c[i]-1; j >= 0; j--)  //从后往前放
		{
			if (b[j] == 0)   //该位置未被占用
			{
				b[j] = a[i];
				flag = true;   
				break;
			}
		}
		if (flag == false)  //该游戏没有时间完成
			m -= a[i];   //扣除对应的钱
	}
	cout << m << endl;
	system("pause");
	return 0;
}

运行截图:
贪心算法-OJ例题_第2张图片

你可能感兴趣的:(贪心算法-OJ例题)