百练1661(动态规划)

http://bailian.openjudge.cn/practice/1661
此题思路上不难理解,但是细节太麻烦,很容易写错。
将初始位置视作长度为0的板子,则老鼠向左或向右走之后会落到下一块板子上,老鼠又要向左走或者向右走,此时问题转化为两个形式一样的下落问题。要注意的是老鼠移动的坐标是右减左。

递归代码:

#include
#include
#include
using namespace std;
int n, x, y, maxn;
int ltm[1001], rtm[1001];
struct Board {
    int x1;
    int x2;
    int h;
}board[1001];
bool cmp(Board a, Board b) {
    if (a.h > b.h) return true;
    else return false;
}

int leftcnt(int num);
int rightcnt(int num);

int leftcnt(int num) {
    int i;
    if (ltm[num]==-1) {
        for (i = num + 1; i <= n; i++) {
            if (board[num].x1 >= board[i].x1&&board[num].x1 <= board[i].x2) break;
        }
        if (i == n + 1) {
            if (board[num].h > maxn) ltm[num] = 20001;
            else ltm[num] = board[num].h;
        }
        else {
            if (board[num].h - board[i].h > maxn) ltm[num] = 20001;
            else ltm[num] = board[num].h - board[i].h + min(leftcnt(i) + board[num].x1 - board[i].x1, rightcnt(i) + board[i].x2 - board[num].x1);
        }
    }
    return ltm[num];
}

int rightcnt(int num) {
    int i;
    if (rtm[num] == -1) {
        for (i = num + 1; i <= n; i++) {
            if (board[num].x2 >= board[i].x1&&board[num].x2 <= board[i].x2) break;
        }
        if (i == n + 1) {
            if (board[num].h > maxn) rtm[num] = 20001;
            else rtm[num] = board[num].h;
        }
        else {
            if (board[num].h - board[i].h > maxn) rtm[num] = 20001;
            else rtm[num] = board[num].h - board[i].h + min(leftcnt(i) + board[num].x2 - board[i].x1, rightcnt(i) + board[i].x2 - board[num].x2);
        }
    }
    return rtm[num];
}
int main() {
    int t;
    cin >> t;
    while (t--) {
        memset(ltm, -1, sizeof(ltm));
        memset(rtm, -1, sizeof(rtm));
        cin >> n >> x >> y >> maxn;
        for (int i = 1; i <= n; i++) cin >> board[i].x1 >> board[i].x2 >> board[i].h;
        board[0].x1 = board[0].x2 = x;
        board[0].h = y;
        sort(board, board + n + 1, cmp);
        cout << min(rightcnt(0),leftcnt(0))<< endl;
    }
    return 0;
}

递推代码:(待补充)

你可能感兴趣的:(百练1661(动态规划))