POJ 1661

同入学当时一块交流的朋友都已经发了CVPR,我却还在这里摸鱼焦虑,振作起来振作起来

水题,每次就两种选择,这样就基本上帮我们定义了状态和状态转移方程

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
using namespace std;

const int maxh= 2e4+5;
const int maxn= 1005;
const int INF= 0x3f3f3f3f;

struct Plat
{
	int x1, x2, h;
	Plat(): x1(0), x2(0), h(0) {}
	Plat(int xx1, int xx2, int hh) : x1(xx1), x2(xx2), h(hh) {}
	bool operator < (const Plat &pp) const
	{
		return this->h < pp.h;
	}
}p[maxn];
int t, n, x, y, m;
int dp[maxn][2], ck[maxn][2];

int Dp(int ly, int lr)
{
	if (ck[ly][lr]){
		return dp[ly][lr];
	}

	int ni= 0;
	int cx= lr ? p[ly].x2 : p[ly].x1;
	int h= p[ly].h;
	int nt;
	for (int i= ly-1; i> 0; --i){
		if (h- p[i].h > m){
			ni= -1;
			break;
		}
		if (cx >= p[i].x1 && cx <= p[i].x2){
			ni= i;
			break;
		}
	}

	if (-1 != ni){
		if (0!= ni){
			nt= min(cx-p[ni].x1+Dp(ni, 0), p[ni].x2-cx+Dp(ni, 1));
			dp[ly][lr]= min(nt, dp[ly][lr]);
		}
		else if (h<= m){
			dp[ly][lr]= 0;
		}
	}
	ck[ly][lr]= 1;

	return dp[ly][lr];
}

int main()
{
	scanf("%d", &t);
	while(t--){
		scanf("%d %d %d %d", &n, &x, &y, &m);
		for (int i= 1; i<= n; ++i){
			struct Plat tp;
			scanf("%d %d %d", &(tp.x1), &(tp.x2), &(tp.h));
			p[i]= tp;
		}
		p[n+1]= Plat(x, x, y);

		sort(p+1, p+n+1);
		memset(dp, 0x3f, sizeof(dp));
		memset(ck, 0, sizeof(ck));
		ck[0][0]= ck[0][1]= ck[1][0]= ck[1][1]= 1;
		dp[0][0]= dp[0][1]= 0;
		if (p[1].h<= m){
			dp[1][0]= dp[1][1]= 0;
		}

		Dp(n+1, 0);
		printf("%d\n", dp[n+1][0]+y);
	}

	return 0;
}
posted @ 2021-03-05 21:09  IdiotNe  阅读(44)  评论(0编辑  收藏  举报