ACM集训之排位赛二:贪心 USACO 2018 February Contest, Silver-Rest Stops

版权声明:本文为博主原创文章,转载请注明出自CSDN Authur_gyc https://blog.csdn.net/WHY995987477/article/details/88587139

USACO 2018 February Contest, Silver-Rest Stops

题意

爬山,要求任何时刻女的不能在男的后面,并且女的要尽可能的多吃花草,花草在山路的休息站那里,具有不同的权值。

思路

对于花草,对他们进行排序,优先去吃那些权值高的,对于权值一样高的,优先吃离自己比较近的(贪心的去吃)。这样就能做到吃到的总权值最大化。
要注意的是
1、爬山的速度的单位是s/m,就是走每米要花多少时间,这里我有注意到,没给坑到。
2、结果要开long long

反思

我把自己坑了,看题意觉得用dp,打完后,发现算法虽然没问题,不过因为数据量太大,开不了那么大的二维数组。然后就断了思路,没有想贪心这方面来。

这里贴一段别人写的贪心和dp的区别和联系(https://blog.csdn.net/multiapple/article/details/8852370)

相同点

1、动态规划和贪心算法都是一种递推算法
2、均有局部最优解推导全局最优解

不同点:

贪心算法:
1.贪心算法中,作出的每步贪心决策都无法改变,因为贪心策略是由上一步的最优解推导下一步的最优解,而上一部之前的最优解则不作保留。
2.由(1)中的介绍,可以知道贪心法正确的条件是:每一步的最优解一定包含上一步的最优解。

动态规划算法:
1.全局最优解中一定包含某个局部最优解,但不一定包含前一个局部最优解,因此需要记录之前的所有最优解
2.动态规划的关键是状态转移方程,即如何由以求出的局部最优解来推导全局最优解
3.边界条件:即最简单的,可以直接得出的局部最优解

代码

#include<cstdio>
#include<cstdlib>
#include<string> 
#include<vector>
#include<queue>
#include<algorithm>
#include<cmath>
typedef long long ll;
using namespace std;
ll ans=0;
struct node{
	int x,c;
}b[100005];
ll cmp(node a,node b)
{
	if(a.c==b.c)
		return a.x<b.x;
	return	 a.c>b.c;
}
int main()
{
	ll n,l,rf,rb;
	scanf("%lld %lld %lld %lld",&l,&n,&rf,&rb);
	//不能dp,用贪心做
	for(ll i=1;i<=n;i++) 
	 	scanf("%lld %lld",&b[i].x,&b[i].c);
	sort(b+1,b+1+n,cmp);//按权值大到小,同权近到远排序 
	ll v=rf-rb;// 路程
	ll tx=0;
	for(ll i=1;i<=n;i++)
	{
		if(b[i].x>tx)
		{
			ans+=(b[i].x-tx)*v*b[i].c;
			tx=b[i].x;
		}
	}
	printf("%lld\n",ans);
	return 0;	
}

猜你喜欢

转载自blog.csdn.net/WHY995987477/article/details/88587139