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

对于sample这组数据,你可以先在普通情况下行驶前14段,这时你有2个加速卡以及80%的能量(N2O).在第15和16段用掉2个加速卡,通过第
17段赛道后又可以得到一个加速卡,在第18段赛道使用. 这道本来很简单的dp,wa了一下午,刚开始的状态还是想的比较快的 dp[i][j][k]代表 第i段,有j个加速卡,现在的能量为k。然后就开始了无尽的wa之旅,wa点其实就三个。
首先我把数组给开小了....正好开了dp[10100][3][100],这个错误通过对拍,然后手推错误数据发现了,当时就想打自己,本来以为能ac了,结果还是wa,然后我一口气对拍了10w组b=1的数据,竟然没有错。然后又对拍了1000组 b=5时候的数据...竟然几乎一个对的都没有,仔细一看,原来是把n圈变成n*l段时,把l误用为了n,又想打自己,本来以为可以ac了,结果还是wa,继续对拍,b=5的时候 有3组数据,分别比正确答案多1 . 2 .3 这时候我确定肯定是状态转移出错了。刚开始的状态转移是这样的,当k==0时,情况可能是,在上一段能量到了80,这段攒了一个加速卡,还可能是,上一段有加速卡,并且用了且当时k==0,所以继续用加速卡,这段依然不增加能量,k==0.k>0时,情况可能是,如果有两张能量卡,那么说明是正常走了一段,如果小于两张,则可能是正常走了一段,或者用了一张加速卡。
经过仔细思考,我发现是因为我漏掉了一种我自认为不可能的情况,那就是有了两张卡,然后能量到了100,然后能量变为0,我本来想的是,卡不用白不用,让能量清0肯定不是最优解,但仔细想的话,如果你不想浪费这张新加速卡,就必须在到100的时候用掉原来的某张加速卡,这肯定是有各种反例的。所以这个题教会了我,动态规划的转移方程一定要写出所有符合条件的,不管你认为亏不亏,合不合理。就算亏他也会在转移中被更新,所以要写全。
 #include<cstdio>

 #include<string.h>

 #include<algorithm>

 #define inf 0x3f3f3f3f

 const int maxn=;

 using namespace std;

 int l,n,ans;

 int dp[maxn+][][];

 int a[maxn+];

 int b[maxn+];

 int main()
{
/* freopen("e://duipai//data.txt","r",stdin);
freopen("e://duipai//out2.txt","w",stdout);*/
while(scanf("%d%d",&l,&n)!=EOF){
ans=inf;
memset(dp,inf,sizeof(dp));
for(int i=;i<=l;i++){
scanf("%d",&a[i]);
for(int j=;j<n;j++){
a[j*l+i]=a[i];
}
}
for(int i=;i<=l;i++){
scanf("%d",&b[i]);
for(int j=;j<n;j++){
b[j*l+i]=b[i];
}
}
dp[][][]=;
for(int i=;i<;i++){
dp[i][][i*]=dp[i-][][(i-)*]+a[i];
}
for(int i=;i<=n*l;i++){
for(int j=;j<=;j++){
for(int k=;k<;k+=){
if(i<&&j>) continue;
if(!k){
if(j==){
dp[i][j][k]=min(dp[i][j][k],min(dp[i-][j-][]+a[i],dp[i-][j+][k]+b[i]));
} else if(j==){
dp[i][j][k]=min(dp[i][j][k],min(dp[i-][j-][]+a[i],dp[i-][j][]+a[i]));
} else if(!j) dp[i][j][k]=min(dp[i][j][k],dp[i-][j+][k]+b[i]);
} else if(k){
if(j==){
dp[i][j][k]=min(dp[i][j][k],dp[i-][j][k-]+a[i]);
}
if(j<){
dp[i][j][k]=min(dp[i][j][k],min(dp[i-][j][k-]+a[i],dp[i-][j+][k]+b[i]));
}
}
}
}
}
for(int i=;i<=;i++){
for(int j=;j<;j+=){
ans=min(ans,dp[n*l][i][j]);
}
}
printf("%d\n",ans);
}
return ;
}

hdu1494 跑跑卡丁车(动态规划)的更多相关文章

  1. 增强学习(三)----- MDP的动态规划解法

    上一篇我们已经说到了,增强学习的目的就是求解马尔可夫决策过程(MDP)的最优策略,使其在任意初始状态下,都能获得最大的Vπ值.(本文不考虑非马尔可夫环境和不完全可观测马尔可夫决策过程(POMDP)中的 ...

  2. 简单动态规划-LeetCode198

    题目:House Robber You are a professional robber planning to rob houses along a street. Each house has ...

  3. 动态规划 Dynamic Programming

    March 26, 2013 作者:Hawstein 出处:http://hawstein.com/posts/dp-novice-to-advanced.html 声明:本文采用以下协议进行授权: ...

  4. 动态规划之最长公共子序列(LCS)

    转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...

  5. C#动态规划查找两个字符串最大子串

     //动态规划查找两个字符串最大子串         public static string lcs(string word1, string word2)         {            ...

  6. C#递归、动态规划计算斐波那契数列

    //递归         public static long recurFib(int num)         {             if (num < 2)              ...

  7. 动态规划求最长公共子序列(Longest Common Subsequence, LCS)

    1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...

  8. 【BZOJ1700】[Usaco2007 Jan]Problem Solving 解题 动态规划

    [BZOJ1700][Usaco2007 Jan]Problem Solving 解题 Description 过去的日子里,农夫John的牛没有任何题目. 可是现在他们有题目,有很多的题目. 精确地 ...

  9. POJ 1163 The Triangle(简单动态规划)

    http://poj.org/problem?id=1163 The Triangle Time Limit: 1000MS   Memory Limit: 10000K Total Submissi ...

随机推荐

  1. 通过阿里云域名动态解析 IP 地址

    这两天在家里用树莓派折腾了一个家用服务器,主要用来做 mac 的 Time Machine ,还有就是当做下载机和 nas ,想着平时上班时间家里没人用网络,空着也是空着,就可以利用空闲带宽下个美剧啥 ...

  2. java数据的5种存储位置(转)

    任何语言所编写的程序,其中的各类型的数据都需要一个存储位置,java中书的存储位置分为以下5种: 1.寄存器 最快的存储区,位于处理器内部,但是数量及其有限.所以寄存器根据需求自动分配,无序人为控制. ...

  3. 《java编程思想》:第五章,初始化与清理

    知识点整理: 1.从概念上讲,‘初始化’与‘创建’是彼此独立的,但是在Java中,两者被捆绑在一起,不可分离. 2.区分重载的方法:每个重载的方法都有一个独一无二的参数类型列表. 甚至参数顺序的不同也 ...

  4. arm-linux-gcc4.4.3编译busybox-1.25.0

    系统环境: 1.操作系统:Ubuntu16.04 2.交叉编译工具链:arm-linux-gcc4.4.3 3.busybox源码包:busybox-1.25.0 一.修改Makefile配置 首先解 ...

  5. 对python生成器特性使用的好例子

    1.对序列进行分组的函数(摘自web.py源码utils.py文件中) def group(seq, size): """ Returns an iterator ove ...

  6. Python3解leetcode Single Number

    问题描述: Given a non-empty array of integers, every element appears twice except for one. Find that sin ...

  7. C++与UnrealScript脚本交互

    转自:http://m.blog.csdn.net/blog/qweewqpkn/39932499 一.c++调用uc脚本中的函数 举例: 1. 在脚本MenuManager.uc文件中实现函数: e ...

  8. Redis 教程笔记

    简介: 开源BSD.key-value数据库.数据持久化(可将内存数据保存到磁盘中),提供多种数据结构. 支持数据备份(master-slave模式) 优势: 性能高.数据类型丰富.原子性.其他 Re ...

  9. 【opencv学习笔记三】opencv3.4.0数据类型解释

    opencv提供了多种基本数据类型,我们这里分析集中常见的类型.opencv的数据类型定义可以在D:\Program Files\opencv340\opencv\build\include\open ...

  10. JavaScript高级程序设计学习笔记第十一章--DOM扩展

    1.对 DOM 的两个主要的扩展是 Selectors API(选择符 API)和 HTML5 2.Selectors API Level 1 的核心是两个方法: querySelector()和 q ...