本题是个简单的动态规划题目,其实亚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;
}