您的位置:首页 > 其它

zoj 3627 F - Treasure Hunt II(贪心)

2015-10-27 14:13 239 查看
Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu
Submit Status

Description

There are n cities(1, 2, ... ,n) forming a line on the wonderland. city i and city i+1 are adjacent and their distance is 1. Each city has many gold coins. Now, Alice and her friend Bob make a team to go treasure hunting. They starts at city p, and they want to get as many gold coins as possible in T days. Each day Alice and Bob can move to adjacent city or just stay at the place, and their action is independent. While as a team, their max distance can't exceed M.

Input

The input contains multiple cases.
The first line of each case are two integers n, p as above.
The following line contain n interger,"v1v2 ... vn" indicate the gold coins in city i.
The next line is M, T.
(1<=n<=100000, 1<=p<=n, 0<=vi<=100000, 0<=M<=100000, 0<=T<=100000)

Output

Output the how many gold coins they can collect at most.

Sample Input

6 3
1 2 3 3 5 4
2 1


Sample Output

8

Hint

At day 1: Alice move to city 2, Bob move to city 4.

They can always get the gold coins of the starting city, even if T=0

贪心题。。一开始先尽量往两边走。。。走到最大距离M...

如果M是奇数的话还要考虑最后一步是谁走(因为最后一步只能一个人走,两个人走就超过M了)

然后分配剩下的时间。。如果往作走了i时间,那么往右就只能走t-2*i(因为还要回来)

然后取所有状态的最大值就好了。。。。

具体见代码注释。。。

/*************************************************************************
> File Name: code/zoj/3627.cpp
> Author: 111qqz
> Email: rkz2013@126.com
> Created Time: 2015年10月24日 星期六 17时00分25秒
************************************************************************/

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<stack>
#include<cctype>

#define yn hez111qqz
#define j1 cute111qqz
#define ms(a,x) memset(a,x,sizeof(a))
using namespace std;
const int dx4[4]={1,0,0,-1};
const int dy4[4]={0,-1,1,0};
typedef long long LL;
typedef double DB;
const int inf = 0x3f3f3f3f;

const int N=1E5+7;
LL sum
,v
;

int n,t,m,p;
LL cal( int l,int r)
{
l = max(1,l);
r = min(n,r);//边界处理
return sum[r]-sum[l-1];
}
int main()
{
#ifndef  ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif

while (scanf("%d %d",&n,&p)!=EOF)
{
sum[0] = 0;
for ( int i = 1 ; i <= n ; i++)
{
scanf("%lld",&v[i]);
sum[i] = sum[i-1] + v[i];
}

scanf("%d %d",&m,&t);
int now = m ;
int l,r;
l=r=p;
while (now>=2 &&t>0)  //在到达距离m之前(m为偶数)或m-1之前(m为奇数)时,同时往两边走
{
l--;
r++;
t--;
now = now - 2;

}
LL ans = cal(l,r);   //在往两边走的过程中已经用完时间
LL res;
int mr,ml;
for ( int i = 1 ; i <= t ; i++)  //先往右边走,分配时间
{
mr = r+i;
int  tmp = r-m-(t-2*i); //往右走i时间,再回来还需要i时间
//此时还剩t-2*i时间,可以让之前再r-m位置的向左走到tmp位置
ml = min(l,tmp);        //即使tmp比l大,tmp~l的部分再之前往两边走的过程中已经取过了,所以作端点至少为l
//换言之,要的是分配i时间走右边的时候能走的最长的那个区间
res = cal(ml,mr);
ans = max(ans,res);
// cout<<"mr:"<<mr<<"tmp:"<<tmp<<" ml:"<<ml<<endl;
}

for ( int i = 1 ; i <= t ; i++) //先往左边走,分配时间,同理。
{
ml = l-i;
int tmp = l+m+(t-2*i);
mr =max(r,tmp);
res = cal(ml,mr);
ans = max(ans,res);
}
printf("%lld\n",ans);
}

#ifndef ONLINE_JUDGE
fclose(stdin);
#endif
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: