hdu2059 龟兔赛跑 (还没做)

来源:互联网 发布:最新炒股软件排名 编辑:程序博客网 时间:2024/04/30 13:55

   看了一些博客,这句话印象最深刻:

DP题。理解DP不是一种固定的算法,而是一种思路,是一种用空间换时间的思维方式。开数组记录每一步的最优解,每次比较更新,最后得出的就是整体最优解。

这题每个步骤有个决策,就是在充电站时选择充或不充,每个决策有影响后面的决策。然后就是怎样让每一步达到最优,这时就要用数组记录然后更新,用一个数组记录每一步的最优解,然后再根据决策的不同,将所有可能的情况列出得这一步的最优解,再保存,下来重复操作。这样最后的到的解就为整体的最优解。

   思路:dp[i]:记录到站点i的最短时间,从0 - (i-1) 判断确定加油后到i的时间,因为到i点肯定是由0-(i-1)中的某一点加了油后不再加油直接到达i点最优(即肯定有一个最后加油点)。可能会有疑问,如果之前到某一点 j 时还有余量,那再加油判断是不是会有问题呢?其实不会,如果到j你不加油,那肯定是之前的某k点加油了,而那点dp[k]已计算过了,所以不再考虑j点不加油的情况,所以一直dp下来即可求出到达终点的最短时间。

  dp是一种拿空间换时间的做法,但是状态的每一个特性不可能全部记录下来,那么只挑选有决定性的(思考二维背包到底是哪二维度,dp又记录了什么)。

所以dp也必然含有那么一点贪心的思路。

  #include<iostream>
using namespace std;
#define INF 100000000
int main()
{
    int l,n,c,t,vr,v1,v2,p[110];
    double t1,t2,dp[110],min;   //dp[i]表示到第i个充电站所用最少的时间
    int i,j,temp;
    while(cin>>l)
    {
        scanf("%d%d%d%d%d%d",&n,&c,&t,&vr,&v1,&v2);
        for(i=1;i<=n;i++)
            cin>>p[i];   
        p[0]=0;   //将起点当做第0个充电站
         p[n+1]=l;   //将终点当做第n+1个充电站
         dp[0]=0;
        for(i=1;i<=n+1;i++)
        {
            min=INF;
            for(j=0;j<i;j++)
            {
                temp=p[i]-p[j];
                if(temp>c)
                    t2=1.0*c/v1+1.0*(temp-c)/v2;
                else
                    t2=1.0*temp/v1;
                t2+=dp[j];
                if(j)   //有充电
                    t2+=t;
                if(min>t2)   //找最小的时间
                    min=t2;
            }
            dp[i]=min;
        }
        t1=1.0*l/vr;   //兔子用的时间
         if(t1>dp[n+1])
            printf("What a pity rabbit!\n");
        else
            printf("Good job,rabbit!\n");
    }
    return 0;
}

0 0
原创粉丝点击