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;
}