POJ 1661-Help Jimmy-dp
2016-05-25 18:59
459 查看
一道dp模拟题。
给n个板子和一个初始坐标xy,从x,y开始向下跳,有一个最高的下跳距离。
在板子上走和下跳都消耗时间。计算到达地面的最短时间。
把板子按高度排序
dp[i][0]表示到达第i块板子左边沿的时间,dp[i][1]表示到达右边沿的时间。
则 dp[i][0] = min(dp[k][0]+f(),dp[k][1]+f() ) k为小于i的可以跳到i上的板子。f()表示从k的左/右边沿到i的左边沿需要的时间。
dp[i][1] = min(dp[k][0]+f(),dp[k][1]+f())
注意判断k是否能跳到i上比较麻烦,k这一端的坐标在i内,且k还没有往下跳的板子,因为一块板子的一端只可能跳到唯一的一块板子,或者地面。
最后维护可以直接跳到地面的板子一端的dp值的最小值。
最近做了好多dp水题,然而不想上传,太水了。
给n个板子和一个初始坐标xy,从x,y开始向下跳,有一个最高的下跳距离。
在板子上走和下跳都消耗时间。计算到达地面的最短时间。
把板子按高度排序
dp[i][0]表示到达第i块板子左边沿的时间,dp[i][1]表示到达右边沿的时间。
则 dp[i][0] = min(dp[k][0]+f(),dp[k][1]+f() ) k为小于i的可以跳到i上的板子。f()表示从k的左/右边沿到i的左边沿需要的时间。
dp[i][1] = min(dp[k][0]+f(),dp[k][1]+f())
注意判断k是否能跳到i上比较麻烦,k这一端的坐标在i内,且k还没有往下跳的板子,因为一块板子的一端只可能跳到唯一的一块板子,或者地面。
最后维护可以直接跳到地面的板子一端的dp值的最小值。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1000+10; const int INF = 0x3f3f3f3f; struct Table{ int l,r; int height; bool operator < (const Table &rhs) const { return height > rhs.height; } }table[maxn]; int N,X0,Y0,Max; int T; int dp[maxn][2]; int vis[maxn],next[maxn][2]; bool check(int i,int j) { if(table[j].height - table[i].height <= Max && table[j].height != table[i].height) return true; else return false; } int main() { scanf("%d",&T); while(T--) { scanf("%d%d%d%d",&N,&X0,&Y0,&Max); for(int i=1;i<=N;i++) { scanf("%d%d%d",&table[i].l,&table[i].r,&table[i].height); if(table[i].l > table[i].r) swap(table[i].l,table[i].r); } sort(table+1,table+1+N); memset(vis,0,sizeof vis); memset(next,0,sizeof next); for(int i=0;i<=N;i++) dp[i][0] = dp[i][1] = INF; int ans = INF; int flag = 0; for(int i=1;i<=N;i++) { if(Y0 - table[i].height > Max) break; if(X0 >= table[i].l && X0 <= table[i].r) { dp[i][0] = Y0 - table[i].height + X0 - table[i].l; dp[i][1] = Y0 - table[i].height + table[i].r - X0; vis[i] = true; flag = 1; break; } } if(!flag) { printf("%d\n",Y0); continue; } for(int i=1;i<=N;i++) { for(int j=i-1;j>=1;j--) if(check(i,j) && vis[j]) { if(!next[j][0] && table[j].l <= table[i].r && table[j].l >= table[i].l) { next[j][0] = true; vis[i] = true; dp[i][0] = min(dp[j][0]+table[j].height-table[i].height+table[j].l-table[i].l,dp[i][0]); dp[i][1] = min(dp[j][0]+table[j].height-table[i].height+table[i].r-table[j].l,dp[i][1]); } if(!next[j][1] && table[j].r >= table[i].l && table[j].r <= table[i].r ) { next[j][1] = true; vis[i] = true; dp[i][0] = min(dp[j][1]+table[j].height-table[i].height+table[j].r-table[i].l,dp[i][0]); dp[i][1] = min(dp[j][1]+table[j].height-table[i].height+table[i].r-table[j].r,dp[i][1]); } } //printf("l:%d r:%d \n",dp[i][0],dp[i][1]); } for(int i=N;i>=1;i--) if(vis[i] && table[i].height <= Max) { if(!next[i][0]) ans = min(ans,dp[i][0]+table[i].height); if(!next[i][1]) ans = min(ans,dp[i][1]+table[i].height); //printf("h:%d l:%d r:%d [%d,%d] \n",table[i].height,dp[i][0],dp[i][1],next[i][0],next[i][1]); } printf("%d\n",ans); } }
最近做了好多dp水题,然而不想上传,太水了。
相关文章推荐
- 高斯消元模板啦啦啦..
- 制造业浪费为何高居不下?
- 使用AndroidStudio做项目时出现错误及解决方案
- python 各模块
- windows查看端口号
- 表格或div被撑开的解决办法
- 三级联动
- SQL 代码创建表格以及CRUD
- git的使用入门介绍-2
- Fragment+Activity之间相互切换
- 插入节点
- WIN7输入法不显示问题解决
- AJAX之XML
- hdu-1010 dfs+剪枝
- vs2010 setup 打包 安装 BAT批处理实现自动安装软件功能
- hdu5696区间的价值 -- 2016"百度之星" - 初赛(Astar Round2B)
- 猜数字游戏
- IOS 正则基本使用
- 利用RequestMappingHandlerMapping提取Spring MVC @RequestMapping
- android和js交互