版权声明:本文为博主原创文章,转载请注明出自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;
}