HDU 2059 动态规划

题意:

额,中文题不翻译。

解题思路:

看别人的博客才理解的,由于每个加油站都可以选择加油和不加油,为了把所有情况考虑进去,不妨令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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值