UVA 1632 Alibaba (区间dp)

Alibaba the famous character of our childhood stories would like to be immortal in order to keep
bringing happiness to children. In order to rich this status he needs to prove that he is still able to
do some unusual things. There are n treasures, (n ≤ 10000) each in a different place located along
a straight road. Each treasure has a time limit, after that it vanishes. Alibaba must take all the n
treasures, and he must do it quickly. So he needs to figure out the order in which he should take the
treasures before their deadlines starting from the most favorable position. Alibaba has the list of places
and deadlines of the treasures. A place i is located at distance di from the leftmost end of the road.
The time it takes to take a treasure is instantaneous. Alibaba must find the smallest time by which he
can take all the treasures.
Input
The program input is from a text file. Each data set in the file stands for a particular set of treasures.
For each set of treasures the input contains the number of treasures, and the list of pairs place - deadline
in increasing order of the locations. White spaces can occur freely between the numbers in the input.
The input data are correct. For each set of data the program prints the result to the standard output
on a separate line. The solution is represented by the smallest time by which Alibaba can take all the
treasures before they vanish. If this is not possible then the output is ‘No solution’.
Sample Input
5
1 3
3 1
5 8
8 19
10 15
5
1 5
2 1
3 4
4 2
5 3
Sample Output
11
No solution

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4507

题目大意:n个宝藏在一条直线上,每个宝藏有一个x坐标和消失时间,求一个找宝藏的方案使全部宝藏都能取到且时间最短

题目分析:范围有点大,但就是个区间dp,dp[i][j][0/1]表示在区间[i,j]中找完且当前停在i/j这个点上,转移方程式比较显然

dp[i][j][0] = min(dp[i + 1][j][0] + a[i + 1] - a[i], dp[i + 1][j][1] + a[j] - a[i])

dp[i][j][1] = min(dp[i][j - 1][1] + a[j] - a[j - 1], dp[i][j - 1][0] + a[j] - a[i])

memset会TLE

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int const MAX = 1e4 + 5;
int const INF = 1e9;
int n, dp[MAX][MAX][2], a[MAX], b[MAX];

int main() {
    while(scanf("%d", &n) != EOF) {
        for (int i = 1; i <= n; i++) {
            scanf("%d %d", &a[i], &b[i]);
            dp[i][i][0] = dp[i][i][1] = 0;
        }
        for (int le = 1; le < n; le++) {
            for (int i = 1; i + le <= n; i++) {
                int j = i + le;
                dp[i][j][0] = min(dp[i + 1][j][0] + a[i + 1] - a[i], dp[i + 1][j][1] + a[j] - a[i]);
                if (dp[i][j][0] >= b[i]) {
                    dp[i][j][0] = INF;
                }
                dp[i][j][1] = min(dp[i][j - 1][1] + a[j] - a[j - 1], dp[i][j - 1][0] + a[j] - a[i]);
                if (dp[i][j][1] >= b[j]) {
                    dp[i][j][1] = INF;
                }
            }
        }
        int mi = min(dp[1][n][0], dp[1][n][1]);
        if (mi == INF) {
            printf("No solution\n");
        } else {
            printf("%d\n", mi);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/Tc_To_Top/article/details/81460034