您的位置:首页 > 其它

HDU 2059 动态规划

2016-07-25 09:19 260 查看
题意:

额,中文题不翻译。

解题思路:

看别人的博客才理解的,由于每个加油站都可以选择加油和不加油,为了把所有情况考虑进去,不妨令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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: