UVALive 3610 Log Jumping(贪心)
来源:互联网 发布:数据结构与算法分析pdf 编辑:程序博客网 时间:2024/06/05 08:19
题目链接:点击打开链接
刘汝佳的大白书里面对这道题的归类是可转化为经典问题的DP,但是死活想不出来怎么dp。
反倒是想到了一种类似贪心的思路。
首先,我们可以把跳的路线看做是一个环,并把跳跃的顺序强制规定为【从最左边往右跳到最右边再往左跳】。
初步思路是对木头的左端点排序,然后枚举最左的木头,之后维护上下两个端点(木头)进行dp,就跟双调欧几里得旅行商问题一样。
但是这么做的话时间复杂度为O(n^3),显然不行。
后来发现完全没有这个必要。当你知道最左的木头的时候其实就可以由贪心的策略得到其最长的长度了。
首先当然也是排序,对木头的左端点升序排序。
对于已确定的左端点,分两种情况:
1. 它跳不到下一条木头,那么答案就为1。
2. 它跳的到下一条木头,那么这条木头就默认作为在维护的【环】中的上端点,原来那个就是下端点。于是就可以继续往下扫过去,每条被扫到的木头都放到跟上下端点中的最左的那条相接的位置【也就是说,由上下端点中的最左的那条跳往这一条】,并更新新的端点。
而对于第二步,由于每条木条的长度是一样的,也就是说当上端点被更新之后必定是下端点最左,反之就是上端点最左。
于是我们就可以默认在这种情况下第i条必定由第i-2条跳过去。
枚举然后扫一边就行了,复杂度O(n^2)。
代码如下:
#include<bits/stdc++.h>#define INF 10000000using namespace std;int a[5005];int n,len;inline bool check(int i,int j){return a[i]+len>=a[j];}int main(){int t;scanf("%d",&t);while(t--){scanf("%d%d",&n,&len);for(int i=0;i<n;i++)scanf("%d",&a[i]);sort(a,a+n);int ans=1;for(int i=0;i<n;i++){if(n-i<=ans)break;int pans=1;if(check(i,i+1))pans++;else continue;for(int j=i+2;j<n;j++){if(check(j-2,j))pans++;else break;}ans=max(ans,pans);}printf("%d\n",ans);}}
0 0
- UVALive 3610 Log Jumping(贪心)
- UVALive 3610 Log Jumping
- uva 1372 - Log Jumping(贪心)
- hdoj--1087--Super Jumping! Jumping! Jumping!(贪心)
- UVALive 4959 Jumping monkey
- UVA 1372 - Log Jumping(推理)
- POJ-2181 Jumping Cows(贪心)
- Hust oj 1071 Jumping Jack(贪心)
- UVALive 2757Supermarket(贪心)
- UVALive 6834Shopping (贪心)
- UVA - 1372 Log Jumping
- uvaLive 4475 - Dinner Hall(贪心)
- UVAlive 2322 Wooden Sticks(贪心)
- UVALive 2088 Entropy (贪心 + 哈夫曼编码)
- uvalive 2322 Wooden Sticks(贪心)
- uvalive 3971 - Assemble(二分搜索 + 贪心)
- UVALive 2322 Wooden Sticks(贪心)
- uvalive 3971 - Assemble(二分搜索 + 贪心)
- Pattern用法(正则表达式)
- 电力网络RTMP协议无线直播摄像头
- Android 6.0以后蓝牙扫描及连接不上解决方案
- vim的一些配置
- Error converting bytecode to dex
- UVALive 3610 Log Jumping(贪心)
- CSS布局奇淫技巧之--各种居中
- SQL建表为表和字段设置注释
- gcc制作静态库和动态库总结
- asp.net C#网站项目 获取物理路径、虚拟路径的方法
- ios 3DTouch
- JLabel控件使用方法
- 写在SCOI之前
- 正则表达式 获取 两字符之间的