hdu 2059 龟兔赛跑 (dp)

小记:自己想的转移方程 太复杂了,参考了一下别人的一个转移方程。


思路: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;
}


你可能感兴趣的:(hdu 2059 龟兔赛跑 (dp))