POJ 1661 Help Jimmy(动态规划)
2010-07-07 01:47
447 查看
//动态规划 //将板按高度排序 //记录到达每块板的左右端点所需的最少时间,和每块板从左右两边跳下去的下一块板指针 //从高到低不断迭代更新最少时间所需值 //注意边缘处理和直接落地的情况以及满足最大跳楼高度这些条件 #include<iostream> #include<algorithm> #define INF 1000000000; using namespace std; struct Plat { int x,y,h; int R_next;//从右端点掉下去的下一块板 int L_next;//从左端点掉下去的下一块板 }P[1005]; int Left[1005],Right[1005];//用LEFT和RIGHT来记录从左端点和右端点到下一块板的最短时间 int t,N,X,Y,MAX; int begin; bool confirmL,confirmR; bool cmp(Plat a,Plat b) { return a.h > b.h;//按板高度排序 } void DP() { for(int i = begin;i <= N;++i) { int Lnext = P[i].L_next; int Rnext = P[i].R_next; if(Lnext == N)//如果从左边可以直接跳到地上 { if(P[i].h <= MAX)//满足跳楼最大高度 Left = Right = min(Left[i] + P[i].h,Left ); } else { if(P[i].h - P[Lnext].h <= MAX)//如果到下一块板的高度差满足最大高度 { Left[Lnext] = min(Left[i] + P[i].x - P[Lnext].x + P[i].h - P[Lnext].h,Left[Lnext]);//状态转移 Right[Lnext] = min(Left[i] + P[Lnext].y - P[i].x + P[i].h - P[Lnext].h,Right[Lnext]); } } if(Rnext == N)//如果从右边可以直接跳到地上 { if(P[i].h <= MAX)//满足跳楼最大高度 Left = Right = min(Right[i] + P[i].h,Left ); } else { if(P[i].h - P[Rnext].h <= MAX)//如果到下一块板的高度差满足最大高度 { Left[Rnext] = min(Right[i] + P[i].y - P[Rnext].x + P[i].h - P[Rnext].h,Left[Rnext]);//状态转移 Right[Rnext] = min(Right[i] + P[Rnext].y - P[i].y + P[i].h - P[Rnext].h,Right[Rnext]);//状态转移 } } } } int main() { //freopen("in.txt","r",stdin); scanf("%d",&t); while(t--) { scanf("%d%d%d%d",&N,&X,&Y,&MAX); for(int i = 0;i <= N;++i) Left[i] = Right[i] = INF; P[0].x = -20000; P[0].y = 20000; P[0].h = 0;//初始化地面这块板 for(int i = 1;i <= N;++i) { scanf("%d%d%d",&P[i].x,&P[i].y,&P[i].h); } sort(P,P+N+1,cmp);//按高度排序 for(int i = 0;i <= N;++i)//遍历所有模板,确定每块木板从左右端点跳下去的下一块木板 { confirmL = confirmR = 0; for(int j = i + 1;j <= N;++j) { if(confirmL && confirmR) break; if(P[i].x >= P[j].x && P[i].x <= P[j].y && !confirmL) { P[i].L_next = j; confirmL = 1;//只确定一块 } if(P[i].y >= P[j].x && P[i].y <= P[j].y && !confirmR) { P[i].R_next = j; confirmR = 1;//只确定一块 } } } for(int i = 0;i <= N;++i)//寻找起始点 { if(i == N)//到N的话说明可以直接落地 { Left[i] = Right[i] = Y; begin = i; } else if(P[i].h <= Y && X >= P[i].x && X <= P[i].y) { begin = i; Left[i] = (Y - P[i].h) + (X - P[i].x);//将初始时间状态记录下来 Right[i] = (Y - P[i].h) + (P[i].y - X); break; } } DP(); printf("%d/n",Left ); } return 0; }
相关文章推荐
- [POJ](1661)Help Jimmy ---- 动态规划
- M - Help Jimmy POJ - 1661【动态规划】
- poj 1661 help Jimmy(dp)
- POJ 1661Help Jimmy(dp)
- ACM POJ 1661 Help Jimmy(动态规划)
- Help Jimmy POJ - 1661
- POJ 1661 Help Jimmy(dp)
- poj 1661 Help Jimmy(dp)
- POJ 1661 Help Jimmy (DP)
- POJ - 1661 Help Jimmy(DP)
- M - Help Jimmy POJ - 1661 ——dp
- Help Jimmy POJ - 1661
- 动态规划训练19、最短路 [Help Jimmy POJ - 1661 ]
- POJ 1661 Help Jimmy
- POJ 1661 Help Jimmy——树形dp
- poj1661:Help&nbsp;Jimmy
- POJ 1661 Help Jimmy(DP,注意边界)
- poj1661——Help Jimmy//最短路
- DP-POJ-1661-Help Jimmy
- POJ 1661 Help Jimmy(动态规划--最短下降模板)