UVA1336(區間dp)

區間dp給我的印象一直是O(n3)的
做到這題才發現自己理解的偏差
題解參考:原作者


#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <cmath>
#define LL long long
#define INF 0x3f3f3f3f
#define mod 1000000007
const int maxn = 1005;
using namespace std;
double dp[maxn][maxn][2];
double sum[maxn];
struct node{
    double x,c,d;
    node(){}
    node(double xx, double cc, double dd):x(xx),c(cc),d(dd){}
    bool operator < (const node & p) const{
        return x < p.x;
    }
}plot[maxn];
double cal(int l, int r){
    return sum[r] - sum[l-1];
}
int main(){
    int n;
    double v,x;
    while(scanf("%d%lf%lf",&n,&v,&x) == 3 && n){

        for(int i=1; i<=n; i++)
            scanf("%lf%lf%lf",&plot[i].x,&plot[i].c,&plot[i].d);
        n++;
        sum[0] = 0;
        for(int i=1; i<=n; i++)
            for(int j=i; j<=n; j++)
                dp[i][j][0] = dp[i][j][1] = INF;
        //memset(dp, INF, sizeof(dp);
        plot[n].x = x;//插入初始位置
        plot[n].c = plot[n].d = 0;
        sort(plot+1,plot+1+n);
        for(int i=1; i<=n; i++) sum[i] = sum[i-1] + plot[i].d;
        for(int i=1; i<=n; i++)
            if(plot[i].x == x) {
                dp[i][i][0] = dp[i][i][1] = 0;
                break;
            }
        for(int i=1; i<=n; i++){//區間長度
            for(int j=1; j+i-1<=n; j++){//起點
                int l = j;
                int r = j+i-1;
                double t = (plot[l].x - plot[l-1].x)/v;
                dp[l-1][r][0] = min(dp[l-1][r][0],dp[l][r][0]+(cal(1,l-1)+cal(r+1,n))*t+plot[l-1].c);
                t = (plot[r].x-plot[l-1].x)/v;
                dp[l-1][r][0] = min(dp[l-1][r][0],dp[l][r][1]+(cal(1,l-1)+cal(r+1,n))*t+plot[l-1].c);
                t = (plot[r+1].x - plot[r].x)/v;
                dp[l][r+1][1] = min(dp[l][r+1][1],dp[l][r][1]+(cal(1,l-1)+cal(r+1,n))*t+plot[r+1].c);
                t = (plot[r+1].x-plot[l].x)/v;
                dp[l][r+1][1] = min(dp[l][r+1][1],dp[l][r][0]+(cal(1,l-1)+cal(r+1,n))*t+plot[r+1].c);
            }
        }
        printf("%.lf\n",floor(min(dp[1][n][0],dp[1][n][1])));
    }
}
/*
 3 1 1000
 1010 0 100
 998 0 300
 996 0 3
*/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章