HDU 2059 动态规划

来源:互联网 发布:mac chrome允许flash 编辑:程序博客网 时间:2024/05/17 15:57

题意:

额,中文题不翻译。

解题思路:

看别人的博客才理解的,由于每个加油站都可以选择加油和不加油,为了把所有情况考虑进去,不妨令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;        }}


0 0
原创粉丝点击