http://acm.hdu.edu.cn/webcontest/contest_showproblem.php?pid=1001&ojid=0&cid=3790&hide=0
跑跑卡丁车
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 7 Accepted Submission(s) : 5
Problem Description
跑跑卡丁车是时下一款流行的网络休闲游戏,你可以在这虚拟的世界里体验驾驶的乐趣。这款游戏的特别之处是你可以通过漂移来获得一种
加速卡,用这种加速卡可以在有限的时间里提高你的速度。为了使问题简单化,我们假设一个赛道分为L段,并且给你通过每段赛道的普通耗时Ai和用加速卡的耗时Bi。加速卡的获得机制是:普通行驶的情况下,每通过1段赛道,可以获得20%的能量(N2O).能量集满后获得一个加速卡(同时能量清0).加速卡最多可以储存2个,也就是说当你有2个加速卡而能量再次集满,那么能量清零但得不到加速卡。一个加速卡只能维持一段赛道,游戏开始时没有加速卡。
问题是,跑完n圈最少用时为多少?
加速卡,用这种加速卡可以在有限的时间里提高你的速度。为了使问题简单化,我们假设一个赛道分为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).
(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
一段赛道分为L段有N圈 则可以共分为L*N段
卡丁车的状态共有14中状态 0% %20 40%.........%280
可以用二位dp[i][j]表示第i段j状态的最短时间
k=j+1; 当k=15时 能量清空又跟k=10的状态一致
dp[i+1][k]=main(dp[i+1][k],dp[i][j]+pre[i%L]) /// 不用加速
j>=5时
dp[i+1][j-5]=min(dp[i+1][j-5],dp[i][j]+pos[i%L]//用加速
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
int pre[100001];
int pos[100001];
int dp[10050][15];
const int INF=0x0fffffff;
int main()
{
// freopen("D://ACM/acm.txt","r",stdin);
int L,N;
while(scanf("%d%d",&L,&N)!=EOF)
{
for(int i=0; i<L; i++)
scanf("%d",&pre[i]);
for(int i=0; i<L; i++)
scanf("%d",&pos[i]);
for(int i=1; i<=L*N; i++)
for(int j=0; j<15; j++)
dp[i][j]=INF;
dp[1][1]=pre[0];
for(int i=1; i<L*N; i++)
{
for(int j=0; j<15; j++)
{
int k=j+1;
if(k==15) k=10;
dp[i+1][k]=min(dp[i+1][k],dp[i][j]+pre[i%L]);
if(j>=5)
dp[i+1][j-5]=min(dp[i+1][j-5],dp[i][j]+pos[i%L]);
}
}
int Max=INF;
for(int i=0; i<15; i++)
Max=min(Max,dp[L*N][i]);
printf("%d\n",Max);
}
return 0;
}