Usaco 生气的奶牛 - (dp&滑窗)|(二分&贪心check)
来源:互联网 发布:淘宝首页装修教程视频 编辑:程序博客网 时间:2024/06/10 02:13
生气的奶牛
题目描述
在数轴x上摆放有n(2<=n<=50000)捆干草堆,没有任何两堆在同样的位置,所有的位置均为整数。你可以用弹弓射击射击数轴上的任意地点。如果你用弹弓以R的力度射击x处,那么该处会发生爆炸,爆炸的范围是以R为半径的圆形区域,所以它会使得[x-R,x+R]的所有干草堆同时发生爆炸。这些干草堆的爆炸半径是R-1。它们又会触发连锁反应,第三轮的爆炸的半径为R-2,依次递减。请选择最小的力度射击,使得所有的干草堆全部爆炸。
输入
第一行包含N。接下来N个整数,表示干草堆的位置。所有位置在[0,1000000000]内。
输出
输出最小的力度R,使得所有的干草堆发生爆炸。四舍五入保留一位小数。
样例输入
5
8 10 3 11 1
样例输出
3.0
提示
样例解释:
如果以力度3射击坐标5,则坐标3,坐标8处的干草堆会发生爆炸,然后又会引爆坐标1和坐标10的干草堆,最后引爆坐标11处的干草堆。
来源
usaco gold 2016.1
Solution 1:dp+滑窗
分析:
dp[][0]是一个单调不递减的数列,dp[][1]是一个单调不上升的数列。
就dp[][0]举例:
当距离(a[i]-a[x])较大,dp[x][0]+1较小的时候,由于求两者的较大值,很显然可以调小距离,相应的调大dp[x][0]+1,因此将x往右移。
如果没有这样的更优的x,就只有用max(dp[i-1][0],a[i]-a[i-1])了。
#include<cstdio>#include<algorithm>#include<cstring>using namespace std;#define INF 2000000000#define MAXN 50000int n,a[MAXN+10],dp[MAXN+10][2];void Read(int &x){ char c; while(c=getchar(),c!=EOF){ if(c>='0'&&c<='9'){ x=c-'0'; while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0'; ungetc(c,stdin); return ; } }}void read(){ Read(n); for(int i=1;i<=n;i++) Read(a[i]); sort(a+1,a+n+1);}void DP() //分别dp出把干草堆左面和后面的爆炸完要的最小R{ memset(dp,0,sizeof dp); for(int i=2,x=1;i<=n;i++){ while(x<i&&a[i]-a[x]>dp[x][0]) x++; if(x!=i) dp[i][0]=dp[x][0]+1; else dp[i][0]=max(dp[i-1][0],a[i]-a[i-1]); } for(int i=n-1,x=n;i>=1;i--){ while(x>i&&a[x]-a[i]>dp[x][1]) x--; if(x!=i) dp[i][1]=dp[x][1]+1; else dp[i][1]=max(dp[i+1][1],a[i+1]-a[i]); }}void workout(){ int i=1,j=n; double ans=INF*1.0; while(i<j){ ans=min(ans,max((a[j]-a[i])/2.0,min(dp[i][0],dp[j][1])+1.0)); if(dp[i+1][0]<dp[j-1][1]) i++; else j--; } printf("%.1lf\n",ans);}int main(){ read(); DP(); workout(); return 0;}
二分+贪心check(From Liu Junhao)
这是他的blog链接
粘一个他的代码,珍藏一下
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define MAXN 50000int n,a[MAXN+10],d[MAXN+10];void Read(int &x){ char c; while(c=getchar(),c!=EOF) if(c>='0'&&c<='9'){ x=c-'0'; while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0'; ungetc(c,stdin); return; }}void read(){ Read(n); for(int i=1;i<=n;i++) Read(a[i]); sort(a+1,a+n+1);}bool check(double R){ double mxr,mir; d[1]=0; int i,j; for(i=1;i<=n;){ if(i==n) return 1; for(j=i+1;a[j]-a[i]<=d[i]+1&&j<=n;j++); if(j>i+1) j--; if(a[j]-a[i]>R-1){ mxr=a[i]+R; break; } d[j]=max(d[i]+1,a[j]-a[i]); i=j; if(d[i]>R-2&&d[i]<=R-1){ mxr=a[i]+R; break; } } d[n]=0; for(i=n;i;){ if(i==1) return 1; for(j=i-1;a[i]-a[j]<=d[i]+1&&j;j--); if(j<i-1) j++; if(a[i]-a[j]>R-1){ mir=a[i]-R; break; } d[j]=max(d[i]+1,a[i]-a[j]); i=j; if(d[i]>R-2&&d[i]<=R-1){ mir=a[i]-R; break; } } if(mxr>=mir) return 1; return 0;}double partition(double l,double r){ double mid; int i=0; while(++i<=70){ mid=(l+r)/2; if(check(mid)) r=mid; else l=mid; } return l;}int main(){ read(); printf("%.1lf\n",partition(1,1000000000));}
0 0
- Usaco 生气的奶牛 - (dp&滑窗)|(二分&贪心check)
- #bzoj3036#生气的奶牛(贪心 + 二分 or DP)
- [usaco gold 2016.1]生气的奶牛
- BZOJ 2097 USACO 2010 Dec Gold Exercise 奶牛健美操 二分答案 树形DP 贪心
- [BZOJ2097][Usaco2010 Dec]Exercise 奶牛健美操(二分+树形dp+贪心)
- [BZOJ2097][Usaco2010 Dec]Exercise 奶牛健美操(二分+树形dp+贪心)
- Usaco 奶牛抗议(树状数组+DP+离散化)
- BZOJ 2097 Exercise 奶牛健美操 二分答案+树形DP+贪心
- USACO 2016 Jan Silver 愤怒的奶牛(Angry Cows)
- USACO 2016 Jan Gold 愤怒的奶牛(Angry Cows)
- ACM 130. [USACO Mar08] 游荡的奶牛(dp+BFS)
- so就 (二分答案 dp 贪心)
- USACO 奶牛的锻炼
- bzoj 2097: [Usaco2010 Dec]Exercise 奶牛健美操 (二分答案+贪心)
- USACO-奶牛叠罗汉--交换法贪心思想
- poj3614 Sunscreen贪心+优先队列(怕晒的奶牛)
- 【bzoj2097】[Usaco2010 Dec]Exercise 奶牛健美操 二分答案+树形dp+贪心
- 洛谷2376 奶牛工资(贪心)
- 一个很好用的大数模板
- Android屏幕适配方案:产品级的解决方案
- C++多态
- 经纬度互换和计算距离
- shell实现mysql高可用
- Usaco 生气的奶牛 - (dp&滑窗)|(二分&贪心check)
- response.getWriter().write 中文乱码问题
- X86汇编快速入门
- zookeeper Curator客户端
- 关联规则浅谈以及Apriori算法matlab实现
- Tomcat的常见的组件与部署
- SQLServer数据库通用访问类
- aliyun服务器 在 centos下 挂载新硬盘
- Android4.4之后发送或接收短信后自动删除问题