小记:自己想的转移方程 太复杂了,参考了一下别人的一个转移方程。
思路:Ti[i] 为到第i个充电站的最少花费时间
t[i][j] 为在第i个充电站充满电后,到达第j个充电站所需的时间
则状态转移方程为:
Ti[i] = min(T[j] + t[j][i] + T | j ∈[1,i-1] ) (i∈[1, N])
特别的:
我们将起点和终点也设置为加油站。
那么在起点的加油站 就不需要加T了,T即是充电所需时间
这里因为时间是根据距离和速度 计算出来的,为了避免精度误差,我对距离t[i][j]的计算使用了乘以vt1*vt2两个值相乘的结果,
那么最后的结果只要除以vt1*vt2即可以和兔子的时间比较得出结果。这里注意+T的话也要让T乘以vt1*vt2
code:
#include <iostream> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <map> #include <set> #include <vector> #include <stack> #include <queue> #include <algorithm> using namespace std; #define mst(a,b) memset(a,b,sizeof(a)) #define REP(a,b,c) for(int a = b; a < c; ++a) #define eps 10e-8 const int MAX_ = 10010; const int N = 100010; const int INF = 0x7fffffff; int p[MAX_]; int dp[MAX_][2]; long long t[MAX_][2]; long long Ti[MAX_]; long long cal(int dis, int C, int vt1, int vt2){ if(dis > C){ return (dis - C)*vt1 + C*vt2; } else { return dis*vt2; } } int main(){ int L, N, vr, vt1, vt2, C, T; while(~scanf("%d", &L)){ scanf("%d%d%d", &N, &C, &T); scanf("%d%d%d", &vr, &vt1, &vt2); REP(i, 1, N+1){ scanf("%d", &p[i]); } p[0] = 0; p[N+1] = L; Ti[0] = 0; //printf("Ti:\n"); REP(i, 1, N+2){ long long minm = cal(p[i] - p[0], C, vt1, vt2); REP(j, 1, i){ long long tmp = Ti[j] + T * vt1 * vt2 + cal(p[i]-p[j], C, vt1, vt2); minm = min(minm, tmp); } Ti[i] = minm; //printf("%I64d ", Ti[i]); } //printf("\n"); double tmp = L*1.0/vr, tt = Ti[N+1]*1.0/(vt1*vt2); //printf("%f %f\n", tmp, tt); if(tmp > tt){ printf("What a pity rabbit!\n"); } else printf("Good job,rabbit!\n"); } return 0; }