ZOJ 3627 Treasure Hunt II
来源:互联网 发布:设计协作软件 编辑:程序博客网 时间:2024/04/29 18:23
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3627
题目大意:有n个城市,每个城市有个宝藏值,有两个人现在在s城市,每天每个人都可以走到相邻城市,但是他们之间的距离不能超过m,问t天内他们最多能拿到多少宝藏?
数据在
贪心+模拟
首先,距离没达到m的时候,两人肯定是往相反方向走为最优。
当距离达到m之后,只有2种可能,向左走一段再返回再向右走一段,向右走一段再返回再向左走一段【也就是左边走2次或者右边走2次】
然后我们枚举向右走了多少个城市,可以用O(1)算出来向左最多可以走多少个城市。
然后枚举是左边走了2次还是右边走了2次,记下最大值即可。
另外有个问题 如果m为奇数,两人往相反方向走的时候,会出现多出1步的情况,这时候就要枚举多的这一步是给左边还是给右边,再进行计算。
总的来说算法不难,但是细节处理上比较恶心。
代码:
#include<cstdio>#include<cstring>#include<cstdlib>#include<string>#include<cmath>#include<iostream>#include<algorithm>#include<map>#include<vector>#include<queue>using namespace std;#define sf scanf#define pf printf#define pfn printf("\n");#define ll long long#define INF 0x7fffffff#define EPS (1e-10)#define FEQ(a,b) (fabs((a) - (b)) < EPS)ll n,P,M,T,ans,p,q;ll a[100001],suml[100001],sumr[100001];ll anst;ll ttt;void find(){ ll t,temp; ll ans2=0; if(p-1<=T) ans2 = suml[p-1]; else ans2 = suml[p-1] - suml[p-1-T]; for(int i = q+1; i<=n; i++){ if(i-q>T) break; t = (T - (i-q))/2; if(p-t<=0) temp = suml[p-1]; else temp = suml[p-1] - suml[p-t-1]; temp += sumr[q+1] - sumr[i+1]; if(temp>ans2) ans2 = temp; t = (T - (i-q)*2); if(t>=0){ if(p-t<=0) temp = suml[p-1]; else temp = suml[p-1] - suml[p-t-1]; temp += sumr[q+1] - sumr[i+1]; if(temp>ans2) ans2 = temp; } } anst=max(anst,ans2+ttt);}void D(){ anst=0; bool flagl,flagr; p = q = P; flagl = flagr = true; ttt=0; while(T){ if(q-p+2>M) break; if(flagl) p--; if(flagr) q++; if(p==0){ p++; flagl=false; } if(q==n+1){ q--; flagr=false; } if(flagl) ans += a[p]; if(flagr) ans += a[q]; T--; } if(T==0) return; if(p==0) p++; if(q==n+1) q--; if(p==1&&q==n) {} else if(q-p==M) find(); else { if(p==1) { q++; T--; ans+=a[q]; find(); } else if(q==n) { p--; T--; ans+=a[p]; find(); } else { q++; T--; ttt=a[q]; find(); // ans-=a[q]; q--; p--; ttt=a[p]; find(); } } ans+=anst;}int main(){ while(scanf("%lld %lld",&n,&P)!=EOF){ memset(a,0,sizeof(a)); for(int i=1; i<=n; i++){ scanf("%lld",&a[i]); } memset(sumr,0,sizeof(sumr)); memset(suml,0,sizeof(suml)); suml[0] = 0; suml[1] = a[1]; for(int i=2; i<=n; i++) suml[i] =suml[i-1] + a[i]; sumr[n] = a[n]; for(int i=n-1; i>=1; i--) sumr[i] = sumr[i+1] + a[i]; scanf("%lld %lld",&M,&T); ans = a[P]; D(); printf("%lld\n",ans); } return 0;}
- ZOJ 3627 Treasure Hunt II
- ZOJ 3627 Treasure Hunt II
- ZOJ 3627 Treasure Hunt II
- ZOJ - 3627 Treasure Hunt II
- zoj 3627 Treasure Hunt II (贪心)
- Treasure Hunt II - ZOJ 3627 想法题
- ZOJ 3627 Treasure Hunt II (贪心)
- zoj 1158 Treasure Hunt
- ZOJ Treasure Hunt IV
- zoj 3629 Treasure Hunt IV
- zoj 3626 Treasure Hunt I
- ZOJ 3629 Treasure Hunt IV
- ZOJ 3626 Treasure Hunt I
- Zoj 3629 Treasure Hunt IV
- ZOJ 3626 Treasure Hunt I
- zoj 1158 || poj 1066 Treasure Hunt
- ZOJ 3626 Treasure Hunt I(树形DP)
- ZOJ 3626 Treasure Hunt I 树形背包
- 使用JFreeChart在网页上绘制平滑曲线
- 总结列表
- 桌面应用框架 OneRing
- Spring定时任务配置方法
- flex与javascript互相通信:使用ExternalInterface
- ZOJ 3627 Treasure Hunt II
- 用PHP5.2+APC实现超酷的PHP进度条
- JavaEE Web开发之SSH知识
- QT 中网络传输时显示速度的实现
- Android开发环境的搭建
- 成都传智播客,学生老师共同举杯庆祝初战高胜!
- 继续C++继承的话题
- winForm+html+js
- MulticastSocket API 详解