HDU 2059 动态规划

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sulisulisu/article/details/52020533

题意:

额,中文题不翻译。

解题思路:

看别人的博客才理解的,由于每个加油站都可以选择加油和不加油,为了把所有情况考虑进去,不妨令dp[i]为从起点到第i个加油站所需要的最短时间,那么dp[i]就应该是从0到i-1这些节点充满电然后直接跑到i的最短时间。为什么这样做不会丢失最优解?不妨考虑第4个节点,计算过程中你求出了dp[2]+t2和dp[3]+t3,这就等于说你已经考虑了第3个节点充电或者不充电的情况,

而且此时的dp[2]是它所能取得最小值,同理,dp[1]+t1和dp[2]+t2就表示考虑了第2个节点充电或者不充电的情况,那么有没有考虑第2个节点不充电但是第三个节点充电的情况呢?这里看上去是没有,但是你在计算dp[3]的时候,就已经考虑好了第二个点究竟该不该充电,所以第2个节点不充电但是第三个节点充电的情况可能会包含于dp[3]+t3中,好绕口啊。。

看代码:


#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<utility>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<cmath>
#include<iterator>
#include<stack>
using namespace std;
const double INF=9999999;
const double eps=1e-7;
const int mod=1000007;
const int maxn=50000;
double dp[maxn];
int a[maxn];
int main()
{
        int l,n,c,t,vr,v1,v2;
        while(cin>>l)
        {
                cin>>n>>c>>t;
                cin>>vr>>v1>>v2;
                for(int i=1;i<=n;i++)
                        cin>>a[i];
                memset(dp,INF,sizeof dp);
                sort(a+1,a+1+n);
                a[0]=0;
                a[n+1]=l;
                dp[0]=0;
                for(int i=1;i<=n+1;i++)
                {
                        for(int j=0;j<i;j++)
                        {
                                double tt;
                                if(c>a[i]-a[j])
                                        tt=1.0*(a[i]-a[j])/v1;
                                else
                                        tt=1.0*c/v1+1.0*(a[i]-a[j]-c)/v2;
                                dp[i]=min(dp[i],dp[j]+tt);
                        }
                        dp[i]+=t;//默认充满电
                }

                if(dp[n+1]-t>1.0*l/vr)
                        cout<<"Good job,rabbit!"<<endl;
                if(dp[n+1]-t<1.0*l/vr)
                        cout<<"What a pity rabbit!"<<endl;
        }
}


展开阅读全文

没有更多推荐了,返回首页