hdu2059:龟兔赛跑

hdu2059: http://acm.hdu.edu.cn/showproblem.php?pid=2059
题意:乌龟骑着充满电的电动车从起点出发,途中有n个充电站,离起点的距离为p[i],电动车每次充电后电动时间为t,乌龟电动速度为v1,脚踩电动车速度为v2,兔子恒速为vr,问龟兔输赢。 解法:dp:优化前方程:dp[i][j]表示乌龟上次充电的站点为j,为从起点到i站时间,dp[i][j]=min(dp[i][j],x+dp[j][k]),dp[j][k]为在站点k充电后到j,从起点到j站花费的最短时间(最短因为已经算过了),x为从j站到i站花费的时间,需要3个for。可优化为一维,dp[i]表示从某个站点充电后到达i所用的最短时间,则dp[i]=min(dp[i],dp[j]+x),只需2个for。 优化前code:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int inf=1<<30;
double dp[150][150];
int p[150];
int min(int a,int b)
{
    if(a<b)
        return a;
    else
        return b;
}
int main()
{
    int l,n,c,t,vr,v1,v2;
    double x,mm;
    while(scanf("%d",&l)!=EOF)
    {
        scanf("%d%d%d",&n,&c,&t);
        scanf("%d%d%d",&vr,&v1,&v2);
        for(int i=1;i<=n;i++)
            scanf("%d",&p[i]);
        for(int i=0;i<=n+1;i++)
            for(int j=0;j<=n+1;j++)
                dp[i][j]=inf;
        p[n+1]=l;p[0]=0;dp[0][0]=0;
        for(int i=1;i<=n+1;i++)
        {
            if(p[i]<c)dp[i][0]=1.0*p[i]/v1;
            else  dp[i][0]=1.0*c/v1+1.0*(p[i]-c)/v2;
        }
        for(int i=1;i<=n+1;i++)    //枚举末站点
        {
            for(int j=0;j<i;j++)   //枚举初站点
            {
                if(p[i]-p[j]<c)
                    x=t+1.0*(p[i]-p[j])/v1;
                else
                    x=t+1.0*c/v1+1.0*(p[i]-p[j]-c)/v2;     //求出从j到i的时间
                for(int k=0;k<j;k++)
                    dp[i][j]=min(dp[i][j],x+dp[j][k]);     
            }
        }
        mm=dp[n+1][0];
        for(int i=1;i<=n+1;i++)
            if(dp[n+1][i]<mm)
                mm=dp[n+1][i];
        if(mm<1.0*l/vr)
            printf("What a pity rabbit!\n");
        else
            printf("Good job,rabbit!\n");
    }
}
优化后code:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
double dp[150];
int p[150];
int min(int a,int b)
{
    if(a<b)
        return a;
    else
        return b;
}
int main()
{
    int l,n,c,t,vr,v1,v2;
    double x;
    while(scanf("%d",&l)!=EOF)
    {
        scanf("%d%d%d",&n,&c,&t);
        scanf("%d%d%d",&vr,&v1,&v2);
        for(int i=1;i<=n;i++)
            scanf("%d",&p[i]);
        p[n+1]=l;p[0]=0;dp[0]=0;
        for(int i=1;i<=n+1;i++)
        {
            if(p[i]<c)dp[i]=1.0*p[i]/v1;
            else  dp[i]=1.0*c/v1+1.0*(p[i]-c)/v2;
        }
        for(int i=1;i<=n+1;i++)
        {
            for(int j=0;j<i;j++)
            {
                if(p[i]-p[j]<c)
                    x=t+1.0*(p[i]-p[j])/v1;
                else
                    x=t+1.0*c/v1+1.0*(p[i]-p[j]-c)/v2;
                dp[i]=min(dp[i],dp[j]+x);
            }
        }
        if(dp[n+1]<1.0*l/vr)
             printf("What a pity rabbit!\n");
        else
            printf("Good job,rabbit!\n");
    }
}
/*input:
100
3 20 5
5 8 2
10 40 60
100
3 60 5
5 8 2
10 40 60
output:
Good job,rabbit!
What a pity rabbit!
*/

posted on 2012-07-25 14:04  acmer-jun  阅读(211)  评论(0编辑  收藏  举报

导航