HDU1494 动态规划

来源:互联网 发布:泸沽湖冬天好玩吗 知乎 编辑:程序博客网 时间:2024/06/05 02:07

HDU 1494

题意:

跑跑卡丁车是时下一款流行的网络休闲游戏,你可以在这虚拟的世界里体验驾驶的乐趣。这款游戏的特别之处是你可以通过漂移来获得一种
加速卡,用这种加速卡可以在有限的时间里提高你的速度。为了使问题简单化,我们假设一个赛道分为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 19 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 98 8 8 8 8 8 8 8 8 8 8 8 8 8 1 1 8 8
 
Sample Output
145
题目其实挺简单的。。但就是做不出来,还以为超级难。。。
把能量分为0--14这15种情况,当15时能量就是0了。
dp[i+1][j]表示走过i+1段时,剩下j能量,所用的时间的最小值。
dp[0][j]等于inf,因为状态不存在。
dp[0][0]=0,表示还没开始走,还没有能量时,开始时间为0
j==0 dp[i+1][j] = dp[i][j+5]+b[i+1]表示当一段路能量为5然后i+1段路加速。
j<10 dp[i+1][j] = min(dp[i][j-1]+a[i+1],dp[i][j+5]+b[i+1])表示这一段路加速或者不加的最小值
j>10 dp[i+1][j] = dp[i][j-1]+a[i+1];表示一定这段路不加速
j==10 dp[i+1][j] = min(dp[i][j-1]+a[i+1],dp[i][14]+a[i+1]) 表示只能由14能量+1得到并且不能加速,或者由j-1的能量+1得到
然后注意一下有N圈,数组要扩容。
以下代码:
#include<cstdio>#include<iostream>#include<algorithm> using namespace std;const int maxn = 1e4+10;const int inf = 99999999;int a[maxn];//普通耗时int b[maxn];//加速耗时int dp[maxn][16];//前i段用掉j个加速卡的最短耗时int L,N;int main() {while(~scanf("%d%d",&L,&N)){for(int i=1; i<=L; i++){scanf("%d",&a[i]);}for(int i=1; i<=L; i++){scanf("%d",&b[i]);}a[0] = a[L];b[0] = b[L];for(int i=L+1;i<=L*N;i++){a[i] = a[i%L];b[i] = b[i%L];}for(int j=1; j<15; j++) dp[0][j] =inf;dp[0][0] = 0;for(int i=0; i<L*N; i++) {for(int j=0; j<15; j++) {if(j==0) {dp[i+1][j] = dp[i][j+5]+b[i+1];}else if(j<10){dp[i+1][j] = min(dp[i][j-1]+a[i+1],dp[i][j+5]+b[i+1]);}else if(j>10){dp[i+1][j] = dp[i][j-1]+a[i+1];}if(j==10){dp[i+1][j] = min(dp[i][j-1]+a[i+1],dp[i][14]+a[i+1]);}}}int sum = inf;for(int i=0;i<15;i++){sum = min(sum,dp[L*N][i]);}printf("%d\n",sum);}}



0 0
原创粉丝点击