7.1-动态规划-Help JimmyPOJ1661

题目

输出要求
对输入的每组测试数据,输出一个整数,Jimmy到地面时可能的最早时间。
输入样例
1
3 8 17 20
0 10 8
0 10 13
4 14 3
输出样例
23

if ( 板子k左端正下方没有别的板子) {
         if( 板子k的高度h(k) 大于Max)
                 LeftMinTime(k) = ∞;
         else
                 LeftMinTime(k) = h(k);
          }
else if( 板子k左端正下方的板子编号是m )
         LeftMinTime(k) = h(k)-h(m) +Min( LeftMinTime(m) + Lx(k)-Lx(m),
                                                       RightMinTime(m) + Rx(m)-Lx(k));
}
#include<iostream>
#include<algorithm>
using namespace std;
const int INF = 1000000;
const int MAX = 100;
int Leftmin[MAX] = { INF };
int Rightmin[MAX] = { INF };
int N, X, Y, Max;
int L_min(int i);
int R_min(int i);
struct Ban{
	int x,y;
	int height;
}ban[MAX];
struct Rule{
	bool operator()(const Ban &a, const Ban &b){
		return a.height > b.height;
	}
};
void Print(Ban a[], int size){			//假定初始板子最高,下标为0;总计N+1个板子;
	int i = 0;
	while (i<=N){
		cout << a[i].x<<" " << a[i].y <<" "<< a[i].height << endl;
		++i;
	}
}

int Isllast(int a){
	for (int i = a; i <= N; ++i){		//判断第a个板子右端点下方有无板子;
		if (ban[a].x > ban[i].x)     //如果a板的右端点值小于其下方j板的端点值,
                                     //右端点下降时必然落在i板上。返回i板编号;
		{
			return i;
			break;
		}
	}
	return 0;
}
int IsRlast(int a){
	for (int i = a; i <=N; ++i){		//判断第a个板子右端点下方有无板子;
		if (ban[a].y < ban[i].y)     //如果a板的右端点值小于其下方i板的端点值,
                                     //右端点下降时必然落在j板上。返回i板编号;
		{
			return i;
			break;
		}
	}
	return 0;
}


int L_min(int i){
	int m = Isllast(i);		//m:i板左端点下方板子的序号。m=0:没有板子
	if (!m && ban[i].height > Max)
		return INF;
	else if (!m && ban[i].height < Max)
		return ban[i].height;
	else
	{
		int H = ban[i].height - ban[m].height;	//i板到其下方m板的高度
		int tmpL = L_min(m);					
		int Lm = tmpL + ban[i].x - ban[m].x;    //m板左端点下落,最小值
		int tmpR = R_min(m);					
		int Rm = tmpR + ban[m].y - ban[i].x;     //m板右端点下落,最小值
		int tmpl = H + min(Lm, Rm);
		Leftmin[i] = tmpl;
		return Leftmin[i];
	}

}
int R_min(int i){
	int m = IsRlast(i);		//m:i板右端点下方板子的序号。m=0:没有板子
	if (!m && ban[i].height > Max)
		return INF;
	else if (!m && ban[i].height < Max)
		return ban[i].height;
	else
	{
		int H = ban[i].height - ban[m].height;	//i板到其下方m板的高度
		int tmpL = L_min(m);
		int Lm = tmpL + ban[i].y - ban[m].x;	//m板左端点下落,最小值
		int tmpR = R_min(m);
		int Rm = tmpR + ban[m].y - ban[i].y;	//m板右端点下落,最小值
		int tmpr = H + min(Lm, Rm);
		Rightmin[i] = tmpr;
		return Rightmin[i];
	}
}


int main(){
	int t;
	cin >> t;
	while (t--){
		cin >> N >> X >> Y >> Max;
		ban[0].x = X;
		ban[0].y = X;
		ban[0].height = Y;
		for (int i = 1; i <= N; ++i)
		{
			cin >> ban[i].x >> ban[i].y;
			cin >> ban[i].height;
		}
		sort(ban, ban + N + 1, Rule());	//按高度自高向低排序。NOTE:数组自1开始。
		Print(ban, N + 1);
		cout << L_min(0);    //最高层,下标为0
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值