Dp+ hdu 龟兔赛跑 2059

/**
这是别人的思路,挺好,简洁,容易想通。
dp[i]表示:乌龟到达第i个加油站所需要的最短时间
dp[i] = min{dp[i],dp[j] + time}其中j < i and time为j到i点所需要的时间(含加油的时间)
把长度L的路程,看成N+2个加油站(算上起点和终点)
*/
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>

using namespace std;

const int INF = 1000000;
const int MAXN = 110;

double dp[MAXN];

int L;
int N, C, T;
int VR, VT1, VT2;
int pos[MAXN];


int main()
{
    int i,j;
    while( ~scanf("%d", &L) )
    {
        cin>>N>>C>>T;
        cin>>VR>>VT1>>VT2;
        for(i = 1; i <= N; ++i)
            cin>>pos[i];
        pos[0] = 0;
        pos[N+1] = L;
        double rabtime = ( L*1.0/VR);//兔子的时间
        for(i = 0; i < MAXN; ++i)
            dp[i] = INF;
        dp[0] = 0;
        for(i = 1; i <= N+1; ++i)//从第一个加油站开始向后遍历
        {
            for(j = 0; j < i; ++j)
            {
                double time;//一下是选择在j加油站加油后到i的时间
                if( pos[i] - pos[j] <= C )
                    time = (pos[i] - pos[j])*1.0/VT1 + T;
                else
                    time = (C*1.0)/VT1 + (pos[i] - pos[j] - C)*1.0 / VT2 + T;
                if( !j )//起点时已经是满的,无需充电
                    time = time - T;
                dp[i] = min( dp[i], dp[j] + time);//到达第i个加油站所需要的最短时间(包括了在i之前的那些加油站所选择的加与不加的情况)
            }
        }
        if( dp[ N+1 ]  >= rabtime )
            cout<<"Good job,rabbit!"<<endl;
        else
            cout<<"What a pity rabbit!"<<endl;
    }
    return 0;
}



你可能感兴趣的:(dp,龟兔赛跑,动态转移方程)