CodeForces 460C--- Present(二分+贪心,还有个地方会TLE)
2015-05-05 18:16
633 查看
本题链接
本题 大意就是 给你一个数组 ,大小表示 花的高度 输入告诉你 花的个数,浇几天花(一天长一个单位)和浇花能覆盖花的个数,问你 浇完后高度最小值的最大情形。
虽然最近 刚学了二分 自认为 还是了解比较清楚,但是做这题开始没看出来是二分,惭愧。。。。
这题就是明显二分,在0~1e10范围内二分,看能满足这个题意的值。有个细节要注意,在模拟浇花那一个范围內花都会被 浇的时候,开始就想直接一个for(),将 存差值的b[i]数组依次减就好,多好理解啊,妈蛋 结果在cf的第20个测试数据TLE了,(cf真的很棒可以看后台测试数据和别人的代码)想想 也对 ,两个for,O(n^2)肯定超时啊,后来看了别人的题解,知道这里有一个 O(n)的解决办法,就是多一个数组c[i]存每次到哪里就不浇花,开始让x,存每次减去要交几次水的个数,再让x+c[i],就是这个点到底有没有被前面教的水覆盖到。
先上 原来明了但是TLE的代码
下面 是优化了浇水时覆盖一片花的AC代码
写完这题,感觉贪心的思想几乎没有,还是考对二分的理解
本题 大意就是 给你一个数组 ,大小表示 花的高度 输入告诉你 花的个数,浇几天花(一天长一个单位)和浇花能覆盖花的个数,问你 浇完后高度最小值的最大情形。
虽然最近 刚学了二分 自认为 还是了解比较清楚,但是做这题开始没看出来是二分,惭愧。。。。
这题就是明显二分,在0~1e10范围内二分,看能满足这个题意的值。有个细节要注意,在模拟浇花那一个范围內花都会被 浇的时候,开始就想直接一个for(),将 存差值的b[i]数组依次减就好,多好理解啊,妈蛋 结果在cf的第20个测试数据TLE了,(cf真的很棒可以看后台测试数据和别人的代码)想想 也对 ,两个for,O(n^2)肯定超时啊,后来看了别人的题解,知道这里有一个 O(n)的解决办法,就是多一个数组c[i]存每次到哪里就不浇花,开始让x,存每次减去要交几次水的个数,再让x+c[i],就是这个点到底有没有被前面教的水覆盖到。
先上 原来明了但是TLE的代码
[code]#include<cstdio> #include<algorithm> #include<cstring> using namespace std; long long a[210000],b[210000]; int main() { long long n,m,w; scanf("%I64d %I64d %I64d",&n,&m,&w); for(long long i=1;i<=n;i++) scanf("%I64d",&a[i]); long long low=0,mid,top=1e10,ans=-1; while(low<=top) { mid=(low+top)/2; memset(b,0,sizeof(b)); for(long long i=1;i<=n;i++) { b[i]=max(mid-a[i],(long long)0); } long long d=m; for(long long i=1;i<=n;i++) { if(b[i]>0) { d-=b[i]; if(d<0) break; long long c=b[i]; for(long long j=i;j<i+w;j++) { b[j]-=c; } b[i]=0; } } if(d<0) { top=mid-1; } else { ans=mid; low=mid+1; } } printf("%I64d\n",ans); return 0; }
下面 是优化了浇水时覆盖一片花的AC代码
[code]#include<cstdio> #include<algorithm> #include<cstring> using namespace std; long long a[100010],b[100010],c[100010];//c是用来实现,浇水时一朵花覆盖到其他几朵的功能,具体实现看后面。 int main() { long long n,m,w; scanf("%I64d %I64d %I64d",&n,&m,&w); for(long long i=1;i<=n;i++) scanf("%I64d",&a[i]); long long low=0,mid,top=1e10,ans=-1; while(low<=top)/=要有 { mid=(low+top)/2; for(long long i=1;i<=n;i++) { b[i]=max(mid-a[i],(long long)0); } memset(c,0,sizeof(c)); long long d=m,x=0; for(long long i=1;i<=n;i++) { x+=c[i];//判断这个点有没有被前面教的水覆盖到 b[i]-=x;/处理之后的b[i]才是这个点面对前面教其他花后,自己有没有被浇到后的差值 if(b[i]>0) { d-=b[i]; if(d<0) break; x+=b[i]; c[i+w]-=b[i]; b[i]=0; } } if(d<0) { top=mid-1; } else { ans=mid;//存每一次中间值 low=mid+1; } } printf("%I64d\n",ans); return 0; }
写完这题,感觉贪心的思想几乎没有,还是考对二分的理解
相关文章推荐
- CodeForces 460C--- Present(二分+贪心)
- Codeforces 460C Present (贪心 + 二分)
- CodeForces 460C——二分+前缀和—— Present
- Codeforces 460C Present(二分)
- codeforces 460C - Present 二分加模拟
- Present - CODEFORCES, 460c 二分 扫描线求和
- Codeforces 460C Present 二分+前缀和
- codeforces 460 C Present 二分+贪心 最大化最小值问题
- Codefores 460C-Present(二分+贪心)
- Codeforces 460C —— Present(二分答案)
- codeforces 349C Mafia [贪心]/[二分答案]
- Codeforces 460C Present
- CodeForces - 363D Renting Bikes (二分+贪心)
- Codeforces - 831D. Office Keys - dp、二分+贪心
- Codeforces 589F Gourmet and Banquet(二分+贪心)
- CodeForces - 363D Renting Bikes(二分,贪心)
- CodeForces 363D.Renting Bikes(二分+贪心)
- C. Present(二分加贪心)
- Codeforces 732D Exams【贪心+二分】
- codeforces 738C Road to Cinema 贪心+二分