poj1661 Help Jimmy(DP)
2015-09-14 21:11
309 查看
题目链接:
http://poj.org/problem?id=1661
题目大意:中文题。
思路:这个题目可以用DP。
对于这个问题,要求总的时间最短。如果在某一块板上,可以选择往左或者往右走。如果此刻我们知道了往左走和往右走到达地面所用的最短时间,那么我们就可以判断出往哪个方向走是最优的。如果我们设置dp[i][j],dp[0][i]表示在第i块板上往左走的最短时间,dp[1][i]表示在第i块板上往右走的最短时间,可以得到状态转移方程:
dp[0][i]=h[i]-h[j]+min(dp[0][j]+x1[j]-x1[i],dp[1][j]+x2[i]-x1[j]);
dp[1][i]=h[i]-h[j]+min(dp[0][j]+x2[i]-x1[j],dp[1][j]+x2[j]-x2[i]);
注意要对木板的高度进行排序,这里可以从小到大进行排序。
这里还有一个要点就是:可能他可以直接跳。所以要额外判断。
代码:
http://poj.org/problem?id=1661
题目大意:中文题。
思路:这个题目可以用DP。
对于这个问题,要求总的时间最短。如果在某一块板上,可以选择往左或者往右走。如果此刻我们知道了往左走和往右走到达地面所用的最短时间,那么我们就可以判断出往哪个方向走是最优的。如果我们设置dp[i][j],dp[0][i]表示在第i块板上往左走的最短时间,dp[1][i]表示在第i块板上往右走的最短时间,可以得到状态转移方程:
dp[0][i]=h[i]-h[j]+min(dp[0][j]+x1[j]-x1[i],dp[1][j]+x2[i]-x1[j]);
dp[1][i]=h[i]-h[j]+min(dp[0][j]+x2[i]-x1[j],dp[1][j]+x2[j]-x2[i]);
注意要对木板的高度进行排序,这里可以从小到大进行排序。
这里还有一个要点就是:可能他可以直接跳。所以要额外判断。
代码:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int min(int a,int b) { if(a<b)return a; else return b; } struct node { int x1,x2,h; }p[1005]; bool cmp(node a,node b) { if(a.h==b.h)return a.x1<b.x1; return a.h<b.h; } int main() { int T,i,j,k,dp[2][20005],n,x,y,MAX,sum,as; bool f; scanf("%d",&T); while(T--) { sum=0; memset(dp,0,sizeof(dp)); scanf("%d%d%d%d",&n,&x,&y,&MAX); for(i=1;i<=n;i++) scanf("%d%d%d",&p[i].x1,&p[i].x2,&p[i].h); sort(p+1,p+1+n,cmp); p[n+1].x1=x;p[n+1].x2=x; p[n+1].h=y; //最后一个赋为起点。 for(i=1;i<=n+1;i++) //从低到高来看,求得dp的最优值 { f=false; for(j=i-1;j>0;j--) //左 { if(p[i].h-p[j].h<=MAX&&p[i].h>p[j].h) //这里要判断是否不超过最大高度。 { if(p[j].x1<=p[i].x1&&p[i].x1<=p[j].x2) //判断是否可以跳到下一块,一旦可以就跳下去,因为也只能跳下去。 { dp[0][i]=p[i].h-p[j].h+min(dp[0][j]+p[i].x1-p[j].x1,dp[1][j]+p[j].x2-p[i].x1); f=true; break; } } } if(p[i].h-p[0].h>MAX&&f==false)dp[0][i]=99999999; //如果没有一块可以跳,那么就直接跳到地面 else if(f==false)dp[0][i]=p[i].h; f=false; for(j=i-1;j>0;j--) //右 { if(p[i].h-p[j].h<=MAX&&p[i].h>p[j].h) { if(p[i].x2>=p[j].x1&&p[j].x2>=p[i].x2) {dp[1][i]=p[i].h-p[j].h+min(dp[0][j]+p[i].x2-p[j].x1,dp[1][j]+p[j].x2-p[i].x2); f=true; break;} } } if(p[i].h-p[0].h>MAX&&f==false)dp[1][i]=99999999; else if(f==false)dp[1][i]=p[i].h; } printf("%d\n",min(dp[0][n+1],dp[1][n+1])); } return 0; }
相关文章推荐
- Objectice-C 【NSMutableDictionary 】
- 用闭包可以解决publish的数据不释放的问题
- Hibernate-常用API简列
- UIView
- Android, 启动活动的最佳写法
- 记hbase list 命令报错zookeeper连接失败
- PHP phpMyAdmin
- 把电脑上的视频导入苹果6
- 事务
- Intellij idea 第一天
- [c] poj2524 并查集
- 一个好的截图软件
- 基于第三方QQ授权登录和新浪微博授权登录的iOS代码分析
- hdu 5446 Unknown Treasure(Lucas定理+中国剩余定理)
- 去掉导航栏下的分割线的方法
- Ubuntu下安装android studio的时候,无法进入图形界面--/usr/lib/jdk1.8.0_60/jre/lib/i386/libawt_xawt.so: libXtst.so.6: 无法打开共享对象文件: 没有那个文件或目录
- [PHP动态]0001.关于 PHP 7 你必须知道的五件事
- Seafile服务器配置
- OpenGL 第一课
- jQuery登录界面,不用跳转页面即可提交post,可以从服务器端获取返回数据