HDU - 1494 跑跑卡丁车(转化题意,将三个状态转化为两个状态)

题目链接:https://cn.vjudge.net/contest/313189#problem/N

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

问题是,跑完n圈最少用时为多少?

Input
每组输入数据有3行,第一行有2个整数L(0 (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

分析:
涉及三个条件:1.能量,2.加速卡,3.走到第几段

  1. 将加速卡也转化为能量:
    加速卡也可以看做能量,玩家最多拥有15个单位的氮气(20%=1个单位)
  2. 定义dp[i][j]
    dp[i][j]:到达第i段,此时拥有j氮气,所需的最少时间
  3. 特殊情况处理
    若氮气等于15,此时相当于有两张加速卡,并且能量也集满了,此时氮气值为10,相当于能量减为0
    若氮气大于5,相当于有加速卡,可以考虑使用加速卡来加速

完整代码

#include
#include
#include
#include
#include
using namespace std;
const int MAX=1e2+10;
const int INF=0x3f3f3f3f;
//加速卡可以看做能量,最多拥有15个单位的氮气(20%==1个单位)
int dp[MAX*MAX][20];//dp[i][j]:到达第i段路,此时拥有j氮气,至少跑了多长时间
int oil[2][MAX];
int L,N;
int main()
{
     
	while(~scanf("%d%d",&L,&N))
	{
     
		for(int i=0; i<2; i++)
			for(int j=0; j<L; j++)
				scanf("%d",&oil[i][j]);
		int k=L*N;//总的需要走k段
		for(int i=1; i<=k; i++)
			for(int j=0; j<15; j++)
				dp[i][j]=INF;

		dp[1][1]=oil[0][0];
		for(int i=1; i<k; i++)
		{
     
			for(int j=0; j<15; j++)
			{
     
				int ta=j+1;
				if(ta==15)
					ta=10;
				dp[i+1][ta]=min(dp[i+1][ta],dp[i][j]+oil[0][i%L]);
				if(j>=5)
					dp[i+1][j-5]=min(dp[i+1][j-5],dp[i][j]+oil[1][i%L]);
			}
		}
		int mi=INF;
		for(int i=0; i<15; i++)
			mi=min(mi,dp[k][i]);
		printf("%d\n",mi);
	}
	return 0;
}

你可能感兴趣的:(动态规划1---子序列问题)