UVa 1336 Fixing the Great Wall (区间DP)

Posted dwtfukgv

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVa 1336 Fixing the Great Wall (区间DP)相关的知识,希望对你有一定的参考价值。

题意:给定 n 个结点,表示要修复的点,然后机器人每秒以 v 的速度移动,初始位置在 x,然后修复结点时不花费时间,但是如果有的结点暂时没修复,

那么每秒它的费用都会增加 d,修复要花费 c,坐标是 pos,问你最少花费是多少。

析:dp[i][j][k] 表示已经修复了 i-j 区间,并且当前在 k,那么两种方案,向左移动,或者向右移动,最后输出就好了。

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#define print(a) printf("%d\n", (a))
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 1e3 + 5;
const int mod = 1e9 + 7;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *Hex[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline int Min(int a, int b){ return a < b ? a : b; }
inline int Max(int a, int b){ return a > b ? a : b; }
inline LL Min(LL a, LL b){ return a < b ? a : b; }
inline LL Max(LL a, LL b){ return a > b ? a : b; }
inline bool is_in(int r, int c){
    return r >= 0 && r < n && c >= 0 && c < m;
}
struct Node{
    int pos, cost, det;
    bool operator < (const Node &p) const{
        return pos < p.pos;
    }
};
Node a[maxn];
double sum[maxn], v;
double dp[maxn][maxn][2];

double cal(int i, int j, int l, int r){
     double t = 1.0 * fabs(a[l].pos-a[r].pos) / v;
     double ans = sum[i-1] + sum[n+1] - sum[j];
     return ans * t;
}

int solve(){
    for(int i = 0; i <= n+1; ++i)
        for(int j = 0; j <= n+1; ++j)
            dp[i][j][0] = dp[i][j][1] = inf;

    int p = lower_bound(a+1, a+n+1, (Node){m, 0, 0}) - a;
    dp[p][p][0] = dp[p][p][1] = 0.0;

    for(int i = p; i > 0; --i){
        for(int j = p; j <= n+1; ++j){
            dp[i-1][j][0] = min(dp[i-1][j][0], dp[i][j][0]+cal(i, j, i, i-1)+a[i-1].cost);
            dp[i-1][j][0] = min(dp[i-1][j][0], dp[i][j][1]+cal(i, j, j, i-1)+a[i-1].cost);
            dp[i][j+1][1] = min(dp[i][j+1][1], dp[i][j][0]+cal(i, j, i, j+1)+a[j+1].cost);
            dp[i][j+1][1] = min(dp[i][j+1][1], dp[i][j][1]+cal(i, j, j, j+1)+a[j+1].cost);
        }
    }
    return min(dp[1][n+1][0], dp[1][n+1][1]);
}

int main(){
    while(scanf("%d %lf %d", &n, &v, &m) == 3 && n+v+m){
        for(int i = 1; i <= n; ++i)  scanf("%d %d %d", &a[i].pos, &a[i].cost, &a[i].det);
        a[n+1].pos = m;  a[n+1].cost = a[n+1].det = 0;
        sort(a+1, a+n+2);
        sum[0] = 0;
        for(int i = 1; i <= n+1; ++i) sum[i] = sum[i-1] + a[i].det;

        int ans = solve();
        printf("%d\n", ans);
    }
    return 0;
}

 

以上是关于UVa 1336 Fixing the Great Wall (区间DP)的主要内容,如果未能解决你的问题,请参考以下文章

UVa 1336 Fixing the Great Wall (区间DP)

UVA10256 The Great Divide(凸包相交)

UVA1045 The Great Wall Game

UVA 10256 The Great Divide (判断凸包相交)

UVA 10256 The Great Divide (凸包,多边形的位置关系)

UVA10256 The Great Divide