zoukankan      html  css  js  c++  java
  • [HDU] 2059 龟兔赛跑 有点暴力性质的dp

    View Code
    #include<iostream>
    //#include<math.h>
    //#include<algorithm>
    //#include<queue>
    //#include<stack>
    using namespace std;
    int const MAX =0x3f3f3f3f;
     
    struct state
    {
        int remainDriving;
        int divingDist;
        int fDist;
        double time;
    };
    int main()
    {
        int totalLengh;
        int chargerCount,drivingDist,chargingDuration;
        int r_speed,t_dSpeend,t_fSpeed;
        int dist[102];
        while(scanf("%d",&totalLengh)!=EOF)
        {
             state dp[102][102];
             memset(dp,0,sizeof(dp));
             scanf("%d %d %d",&chargerCount,&drivingDist,&chargingDuration);
             scanf("%d %d %d",&r_speed,&t_dSpeend,&t_fSpeed );
             for(int i=1;i<=chargerCount;i++)
                scanf("%d",&dist[i]);
             dist[0]=0;
             dist[chargerCount+1]=totalLengh;
             dp[0][0].divingDist=0;
             dp[0][0].fDist=0;
             dp[0][0].remainDriving = drivingDist;
             dp[0][0].time=0.0;
             for(int i = 1;i<=chargerCount+1;i++)
             {
                 double minTime = MAX+0.0;
                 int minIndex;
                 for(int j=0;j<i;j++)
                 {
                     if(dp[j][i-1].remainDriving <= dist[i]-dist[i-1])
                     {
                         dp[j][i].divingDist = dp[j][i-1].remainDriving;
                         dp[j][i].fDist = dist[i]-dist[i-1]-dp[j][i-1].remainDriving;
                         dp[j][i].remainDriving = 0; 
                     }
                     else
                     {
                         dp[j][i].divingDist = dist[i]-dist[i-1];
                         dp[j][i].fDist = 0;
                         dp[j][i].remainDriving = dp[j][i-1].remainDriving -(dist[i]-dist[i-1]); 
                     }
                     dp[j][i].time = dp[j][i-1].time + (double)dp[j][i].divingDist/(double)t_dSpeend + (double)dp[j][i].fDist/(double)t_fSpeed;
                     if(minTime>dp[j][i].time)
                     {
                        minTime = dp[j][i].time;
                        minIndex = j;
                     }
                 }
                 dp[i][i].divingDist = dp[minIndex][i].divingDist;
                 dp[i][i].fDist = dp[minIndex][i].fDist;
                 dp[i][i].time =  dp[minIndex][i].time+(double)chargingDuration;
                 dp[i][i].remainDriving = drivingDist;
             }
             double temp = (double)MAX;
         
             for(int i=0;i<chargerCount+1;i++)
             {
                 if(dp[ i][chargerCount+1].time<temp)
                     temp = dp[i][chargerCount+1].time;
             }
             double r_t = (double)totalLengh/(double)r_speed;
             if(r_t>temp)
                 cout<<"What a pity rabbit!"<<endl;
             else
                 cout<<"Good job,rabbit!"<<endl;
                
        }
        return 0;
    } 
    
     
    
     
    
     

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=2059

    方法:设F(i,n)  (0<=i<n)来表示当到达第n个加油站的时候,在前面的n-1个加油站中的第i个加油站加油其他加油站不加油的前进情况,i的0表示是刚出发的那个位子,把那个位子也模拟成一个加油站,当然它只有一个选择,那就是加满了油的。这些前进情况包含几个信息:从上一个加油站到此骑车前进的距离drivingDist,从上一个加油站到此步行前进的距离fDist,从开始到此一共花的时间time以及当前还剩余多少距离可以骑车前进remainDriving。

    当i==n的时候,这个表示成在该站要加油,这个时候,需要消耗的时间当然是以上状态中最快的那个时间加上加油的时间,因为不管以上状态还,还可以继续骑车的距离有多么不同,只要一加了油,都会同一继续骑车的剩余距离,那就是加满油的骑车前进距离。既然如此那当然选择以上状态中最快的一个F(fastest,n),这样的选择其实就会涵盖前面几个加油站加油还是不加油,是连续几个加油站都加油还是怎么这些组合可能的考虑,最后设置加油后的前进状态。设两个加油站k,j间的距离为S(k,j)

    状态转移方程:

        {

          [  

             drivingDist = F(i,n-1).remainDriving >= S(n-1,n) ? S(n-1,n):  F(i,n-1).remainDriving,

             remainDriving = F(i,n-1).remainDriving >= S(n-1,n) ?  F(i,n-1).remainDriving-S(n-1,n):  0,

             fDist = F(i,n-1).remainDriving >= S(n-1,n) ?  0:S(n-1,n)-F(i,n-1).remainDriving,

             time =  F(i,n-1).time + drivingDist/骑车速度 + fDist/步行速度

          ], 0<=i<n;

    F(i,n) =  [  

               除 time外的所有信息都和F(fastest,n) 的相同,

            time = Min({  F(i,n).time | 0<=i<n}) + 加油消耗时间

          ], i==n;

       }

    而最后问题的解为:Min( {F(i,N).time | 1<=i<=N})

    最后拿这个解去和兔子比速度。

    感谢:细心,注意小数运算。

    代码:

    View Code
    #include<iostream>
    //#include<math.h>
    //#include<algorithm>
    //#include<queue>
    //#include<stack>
    using namespace std;
    int const MAX =0x3f3f3f3f;
     
    struct state
    {
        int remainDriving;
        int divingDist;
        int fDist;
        double time;
    };
    int main()
    {
        int totalLengh;
        int chargerCount,drivingDist,chargingDuration;
        int r_speed,t_dSpeend,t_fSpeed;
        int dist[102];
        while(scanf("%d",&totalLengh)!=EOF)
        {
             state dp[102][102];
             memset(dp,0,sizeof(dp));
             scanf("%d %d %d",&chargerCount,&drivingDist,&chargingDuration);
             scanf("%d %d %d",&r_speed,&t_dSpeend,&t_fSpeed );
             for(int i=1;i<=chargerCount;i++)
                scanf("%d",&dist[i]);
             dist[0]=0;
             dist[chargerCount+1]=totalLengh;
             dp[0][0].divingDist=0;
             dp[0][0].fDist=0;
             dp[0][0].remainDriving = drivingDist;
             dp[0][0].time=0.0;
             for(int i = 1;i<=chargerCount+1;i++)
             {
                 double minTime = MAX+0.0;
                 int minIndex;
                 for(int j=0;j<i;j++)
                 {
                     if(dp[j][i-1].remainDriving <= dist[i]-dist[i-1])
                     {
                         dp[j][i].divingDist = dp[j][i-1].remainDriving;
                         dp[j][i].fDist = dist[i]-dist[i-1]-dp[j][i-1].remainDriving;
                         dp[j][i].remainDriving = 0; 
                     }
                     else
                     {
                         dp[j][i].divingDist = dist[i]-dist[i-1];
                         dp[j][i].fDist = 0;
                         dp[j][i].remainDriving = dp[j][i-1].remainDriving -(dist[i]-dist[i-1]); 
                     }
                     dp[j][i].time = dp[j][i-1].time + (double)dp[j][i].divingDist/(double)t_dSpeend + (double)dp[j][i].fDist/(double)t_fSpeed;
                     if(minTime>dp[j][i].time)
                     {
                        minTime = dp[j][i].time;
                        minIndex = j;
                     }
                 }
                 dp[i][i].divingDist = dp[minIndex][i].divingDist;
                 dp[i][i].fDist = dp[minIndex][i].fDist;
                 dp[i][i].time =  dp[minIndex][i].time+(double)chargingDuration;
                 dp[i][i].remainDriving = drivingDist;
             }
             double temp = (double)MAX;
         
             for(int i=0;i<chargerCount+1;i++)
             {
                 if(dp[ i][chargerCount+1].time<temp)
                     temp = dp[i][chargerCount+1].time;
             }
             double r_t = (double)totalLengh/(double)r_speed;
             if(r_t>temp)
                 cout<<"What a pity rabbit!"<<endl;
             else
                 cout<<"Good job,rabbit!"<<endl;
                
        }
        return 0;
    } 
  • 相关阅读:
    泛型接口(C# 编程指南) From MSDN
    不知道是不是心理作用,我怎么觉得在Fedora下写cnblogs比Windows下快。
    VS.NET 2005真是太好用了!
    写了个打字游戏,可是有问题(C#)
    C#多线程测试
    关于继承的一个小程序
    VS.NET 2008 试用
    基本排序算法及分析(二):冒泡排序
    基本排序算法及分析(三):shell排序
    [导入]一维数组输出杨辉三角形
  • 原文地址:https://www.cnblogs.com/kbyd/p/3044801.html
Copyright © 2011-2022 走看看