• HDU


    先上题目:

    跑跑卡丁车

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 2145    Accepted Submission(s): 726


    Problem Description
    跑跑卡丁车是时下一款流行的网络休闲游戏,你可以在这虚拟的世界里体验驾驶的乐趣。这款游戏的特别之处是你可以通过漂移来获得一种
    加速卡,用这种加速卡可以在有限的时间里提高你的速度。为了使问题简单化,我们假设一个赛道分为L段,并且给你通过每段赛道的普通耗时Ai和用加速卡的耗时Bi。加速卡的获得机制是:普通行驶的情况下,每通过1段赛道,可以获得20%的能量(N2O).能量集满后获得一个加速卡(同时能量清0).加速卡最多可以储存2个,也就是说当你有2个加速卡而能量再次集满,那么能量清零但得不到加速卡。一个加速卡只能维持一段赛道,游戏开始时没有加速卡。




    问题是,跑完n圈最少用时为多少?
     
    Input
    每组输入数据有3行,第一行有2个整数L(0<L<100),N(0<N<100)分别表示一圈赛道分为L段和有N圈赛道,接下来两行分别有L个整数Ai和Bi
    (Ai > Bi).
     
    Output
    对于每组输入数据,输出一个整数表示最少的用时.
     
    Sample Input
    18 1
    9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9
    8 8 8 8 8 8 8 8 8 8 8 8 8 8 1 1 8 8
     
    Sample Output
    145
     
    Hint
    Hint
    对于sample这组数据,你可以先在普通情况下行驶前14段,这时你有2个加速卡以及80%的能量(N2O).在第15和16段用掉2个加速卡,通过第 17段赛道后又可以得到一个加速卡,在第18段赛道使用.
     
      中文题意。这题一开始想的方法是开一个数组dp[i][j][k]表示对于到达第i段路,有j这么多硝气,同时有k张加速卡这一种状态的时候至少跑了多少时间。后来发现这样设计的话整个程序非常复杂。在网上看了一下别人的代码,发现其实可以直接定义为dp[i][j]表示到达第i段路,当前拥有j硝气这一种状态的时候至少跑了多少时间。这里的j并不止只有储气瓶里面的硝气,加速卡其实是另一种形态的硝气,所以我们可以将两者中一起来,那么玩家最多就可以拥有15个单位的硝气了(20%==1单位)。
      当考察 j 的时候,令k=j+1,意思是当前第i段路,走完以后就有k硝气,当然我们还要判断一下k是否等于15,如果等于15那就满了,同时也就意味着手上已经有两张加速卡,k要变成10。
      状态转移方程:
      考虑不用加速卡的情况:dp[i+1][k]=min{dp[i+1][k],dp[i][j]+c[0][i]}
      如果j>=5,意味着手上有加速卡,那么就可以考虑用加速卡。
      考虑用加速卡的情况:dp[i+1][j-5]=min{dp[i+1][j-5],dp[i][j]+c[1][i]}
      这里需要注意的是是j-5不是k-5因为我们是在第i段路使用加速卡, 第i段路的硝气量应该是j而不是k,k是跑完第i段路以后才拥有的量。
     
    上代码:
     
     1 #include <cstdio>
     2 #include <cstring>
     3 #define min(x,y) (x <= y ? x : y)
     4 #define MAX 102
     5 #define INF 0x0fffffff
     6 using namespace std;
     7 
     8 int dp[MAX*MAX][17];
     9 int c[2][MAX];
    10 
    11 int main()
    12 {
    13     int l,n,m,minn;
    14     //freopen("data.txt","r",stdin);
    15     while(scanf("%d %d",&l,&n)!=EOF){
    16         for(int i=0;i<=1;i++){
    17             for(int j=0;j<l;j++){
    18                 scanf("%d",&c[i][j]);
    19             }
    20         }
    21         m=l*n;
    22         for(int i=1;i<=m;i++){
    23             for(int j=0;j<15;j++){
    24                 dp[i][j]=INF;
    25             }
    26         }
    27         dp[1][1]=c[0][0];
    28         for(int i=1;i<m;i++){
    29             for(int j=0;j<15;j++){
    30                 int k=j+1;
    31                 if(k==15) k=10;
    32                 dp[i+1][k]=min(dp[i+1][k],dp[i][j]+c[0][i%l]);
    33 
    34                 if(j>=5)
    35                 dp[i+1][j-5]=min(dp[i+1][j-5],dp[i][j]+c[1][i%l]);
    36             }
    37         }
    38         minn=INF;
    39         for(int i=0;i<15;i++){
    40             minn=min(minn,dp[m][i]);
    41         }
    42         printf("%d
    ",minn);
    43     }
    44     return 0;
    45 }
    1494
  • 相关阅读:
    JavaScript语言和jQuery技术--2
    Mybatis框架--1
    数据接口请求异常:parsererror
    Callable和Future?
    如何实现拦截器?
    window.onload()函数和jQuery中的document.ready()有什么区别?
    SpringBoot框架 1.什么是 Spring Boot?
    什么是 JavaConfig?
    jquery中$.get()提交和$.post()提交有区别吗?
    什么是线程?
  • 原文地址:https://www.cnblogs.com/sineatos/p/3626833.html
Copyright © 2020-2023  润新知