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;}


原创粉丝点击