Help Jimmy
来源:互联网 发布:网络语开挂是什么意思 编辑:程序博客网 时间:2024/05/17 23:20
Help Jimmy
四步走:
1.原问题分解为子问题
原问题:从最高点到地面所需要的时间
子问题:分为两个.从每个”相对”起点的左边走,或者从”相对结点的”右边走
2.确定状态
所谓的状态就是,各个路径沿途所经过的变量取值
在这个环境中对应起来就是, 各个路径中(从左边走||从右边走)沿途所经过变量(板子的编号)的取值
3.确定状态的边界值
边界不就是最后一行的取值(但是似乎这里不可深究太多,否则深陷递归的沼潭!)
4.确定状态的转移方程
假设从k 出发(看成点),k的正下方为m
LeftMinTime(k) = h(k) - h(m) + min(LeftMinTime(m)+ Lx(k)-Lx(m) +
RightMinTime(m)+Rx(m) - Rx(k) );RightMinTime(k) = h(k) - h(m) + min(LeftMinTime(m)+Lx(k)-Lx(m) +
RightMinTime(m)+Rx(m) - Rx(k) );
再具体分析这个问题时就没那么麻烦了!
注:如果还实在理解不了,建议使用样例在IDE中单步执行,直至理解整个过程!
强调几个需要注意的事情:
1.首先要明确一件事,就是用户的标准输入的板子高度不是按照大小顺序排的,所以首先务必先把高度从高到低进行排序!
一下代码使用的是结构体排序用到cmp,如果不懂参参照另一篇博文:qsort理解2.很明显每次都有两种选择可以使用,那么这时候就要有自己的主见了,
就是自己想怎样走一条路走到黑?(本例程是从左走到黑的)
这种思想颇像那个称硬币枚举那道题,可参见:称硬币
3.看代码注释
#include<stdio.h>#include<memory.h>#include<stdlib.h>#define MAX_N 1000#define INFINITE 1000000int t,n,x,y,max;struct Platform{ int Lx,Rx,h;};Platform aPlatform[MAX_N+10]; //用于存放相关板的信息 Lx Rx 以及 hint aLeftMinTime[MAX_N+10]; //记录某个板(看编号)的左端点是否走过int aRightMinTime[MAX_N+10]; //记录某个板(看编号)的右端点是否走过int MyCompare(const void *a,const void *b){ Platform *p1,*p2; p1=(Platform *)a; p2=(Platform *)b; return p2->h-p1->h;//实现降序排列}int MinTime(int L,bool bLeft)//这里定义成bool类型更节省空间{ int y=aPlatform[L].h;//表示“相对”起点的高度(一块板的左右选相对起点) int x,i; if(bLeft)//假如这块板左边没当过“相对”起点,那就让他做“相对”起点! x=aPlatform[L].Lx; else x=aPlatform[L].Rx; for(i=L+1;i<=n;i++)//判断相对“起点”下的板是否能走,不能走的话就继续找下下块板,直到找到或没板! { if(aPlatform[i].Lx <= x && aPlatform[i].Rx >= x)//判断下一块板的左右端点是否在“相对”起点两侧,至少重合? break;//在的话break掉 } if(i<=n)//下一块板还存在 { if( y - aPlatform[i].h > max )//判断是否会摔死 return INFINITE; } else//没板了 { if( y > max )//这里容易写错,注意是y在比较! return INFINITE;//摔死那就返回无穷大! else return y;//不会摔死返回高度差 } int nLeftTime = y - aPlatform[i].h + x - aPlatform[i].Lx;//“相对”起点出发,从左所用时间 int nRightTime = y - aPlatform[i].h + aPlatform[i].Rx - x;//“相对”起点出发,从右所用时间 if( aLeftMinTime[i] == -1 )//这里的i已经自加,意即判断相对起点下的左端点是否做过“相对”起点? aLeftMinTime[i] = MinTime(i, true);//没有的话继续让他作为“相对”起点。 这里容易写错注意走左边就是true! if( aRightMinTime[i] == -1 )//同上,不过是右边 aRightMinTime[i] = MinTime(i, false); nLeftTime += aLeftMinTime[i];//左边走的总时间 nRightTime += aRightMinTime[i];//右边走的总时间 if( nLeftTime < nRightTime )//返回最小值 return nLeftTime; else return nRightTime;}//其实仔细想想 aLeftMinTime[i]、aRightMinTime[i] 何尝不是最优子结构性质的体现呢?int main(){ int i,j;/* freopen("in.txt","r",stdin);*/ scanf("%d", &t); for( i = 0;i < t; i ++ ) { memset(aLeftMinTime, -1, sizeof(aLeftMinTime)); memset(aRightMinTime, -1, sizeof(aRightMinTime)); scanf("%d%d%d%d", &n, &x, &y, &max); aPlatform[0].Lx = x; aPlatform[0].Rx = x; aPlatform[0].h = y; for(j = 1; j <= n; j ++ ) scanf("%d%d%d", & aPlatform[j].Lx, & aPlatform[j].Rx, & aPlatform[j].h); qsort(aPlatform, n+1, sizeof(Platform), MyCompare); printf("%d\n", MinTime(0, true)); } return 0;}
0 0
- Help Jimmy
- Help Jimmy
- Help Jimmy
- Help Jimmy
- pku 1661 Help Jimmy
- POJ 1661 Help Jimmy
- POJ 1661 Help Jimmy
- poj 1661 Help Jimmy
- 动态规划 Help Jimmy
- poj 1661 Help Jimmy
- poj1661 Help Jimmy
- poj 1661 Help Jimmy
- 【DP】Help Jimmy
- POJ 1661 Help Jimmy
- Help Jimmy(动态规划)
- Poj 1661 Help Jimmy
- poj 1661 Help Jimmy
- poj 1661 Help Jimmy
- angularjs-搜索框下拉列表
- PCA和矩阵
- 关于错误: 'encoding' is an invalid keyword argument for this function的错误原因之一
- ubuntu14.04/16.04 下安装 caffe
- 点9图片入门
- Help Jimmy
- 对于一般的Mat如何进行赋值
- Android开发环境的搭建与HelloWorld
- Coding沙龙之巧用typedef
- Java-jdk的安装,Tomcat服务器的安装,在eclipse中添加JavaEE插件常见问题以及解决方法,步骤
- 用命令行连接MySQL数据库
- Android studio for Mac配置React-native时的坑
- QT 正则表达式 QRegExp 使用
- Aircrack-ng破解无线网络