Jackiesteed

www.github.com/jackiesteed

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

本题是个简单的动态规划题目,其实亚O(N^2)(N==10000)的算法也是过的,但是假如出题人把数据量提高到1e5,程序肯定就会挂的.

通过观察,其实对于station[i]处票价会产生实质性影响的只有3个,这3个分别是station[i]前面距离station[i]小于L[1]的最远的station,距离它小于L[2]最远的,距离它小于L[3]但是最远的.这样,通过station[i]-L[j](j=1,2,3)这个值,就可以在station数组里二分定位我们想要求的station(通过这个station的最优只来更新station[i])的下标了.

至此,程序时间复杂度为O(N*log(N)),处理N==1e6的数量级没问题.

附源代码:

View Code
#include <iostream>
#include
<fstream>
#include
<cstring>
#include
<cstdio>
#include
<climits>
#include
<cstdio>

using namespace std;

typedef
long long LL;

const LL INF=LLONG_MAX;
LL L[
4],C[4];
LL N;
LL S,T;
LL stations[
11000];
LL dp[
11000];

int get(LL val)
{
int lo=S,hi=T;
int mid;

while(lo<=hi)
{
mid
=(lo+hi)/2;
if(stations[mid]>=val)
hi
=mid-1;
else
lo
=mid+1;
}
while(mid>S && stations[mid]>val)
mid
--;
while(mid<T && stations[mid]<val)
mid
++;

return mid;
}

int main()
{
// freopen("input.txt","r",stdin);

for(int i=1;i<=3;i++)
scanf(
"%I64d",&L[i]);
for(int i=1;i<=3;i++)
scanf(
"%I64d",&C[i]);

scanf(
"%I64d",&N);
scanf(
"%I64d %I64d",&S,&T);
if(S>T)
swap(S,T);

for(int i=2;i<=N;i++)
{
scanf(
"%I64d",&stations[i]);
}
dp[S]
=0;
for(int i=S+1;i<=T;i++)
dp[i]
=INF;
LL nIndex;

for(int i=S+1;i<=T;i++)
{
for(int j=1;j<=3;j++)
{
nIndex
=get(stations[i]-L[j]);
if(nIndex!=i && dp[i]>dp[nIndex]+C[j])
{
dp[i]
=dp[nIndex]+C[j];
}
}
}
printf(
"%I64d\n",dp[T]);

return 0;
}

posted on 2011-05-18 09:23  Jackiesteed  阅读(348)  评论(0编辑  收藏  举报