uva1336 Fixing the Great Wall

https://vjudge.net/problem/UVA-1336

 

Obviously the best way to move some must be left to go, goes a right, then goes a left, then go for some right ...... (or vice versa)

In any case it will be the first to fix the middle, so consider the interval dp

$ F_ {i, j, 0/1} $ I $ represents mended \ when rightarrow j $, with minimum costs (the cost calculated in advance note)

Pretreatment at $ cl_ {i, j} (i \ leq j) $ $ represents the starting repair costs from $ J $ $ i

$ Cr_ {i, j} (i \ geq j) $ $ I $ departing from the repair costs $ $ J

Then is transferred (but it is still good to think), because the decision set is not reduced, it is possible to use a mark recorded at a minimum, $ O (1) $ Transfer

 

#include<bits/stdc++.h>
using namespace std;
const int N=1005;
const double inf=1000000000.0,eps=0.000001;
int n,v,x,st;
struct node{int c,d,x;} sec[N];
double f[N][N][2],cl[N][N],cr[N][N];
double sum[N],min0[N],min1[N],bs;
void clear()
{
    st=0,bs=0;
    for(int i=0;i<N;++i)
    {
        sum[i]=0,cl[i][i]=0;
        min0 [i] = min-1 [i] = inf;
    }
}
double tme(int a,int b) {return (double)abs(sec[a].x-sec[b].x)/(double)v;}
bool cmp(node a,node b) {return a.x<b.x;}
int main()
{
    while (scanf("%d%d%d", &n, &v, &x)==3 && n)
    {
        if(!n && !v && !x) return 0;
        clear();
        for(int i=1;i<=n;++i)
            scanf("%d%d%d",&sec[i].x,&sec[i].c,&sec[i].d);
        sort(sec+1,sec+n+1,cmp);
        sec[n+1].x=x+1;
        for(int i=1;i<=n+1;++i)
            if(sec[i].x>x) {st=i-1;break;}
        for(int i=1;i<=n;++i)
            for(int j=i+1;j<=n;++j)
                cl[i][j]=cl[i][j-1]+tme(i,j)*sec[j].d;
        for(int i=1;i<=n;++i)
            for(int j=i-1;j>=1;--j)
                cr[i][j]=cr[i][j+1]+tme(i,j)*sec[j].d;
        for(int i=1;i<=n;++i) sum[i]=sum[i-1]+sec[i].d,bs+=sec[i].c;
        if(!st) {
            printf("%.0lf\n",floor(bs+cl[1][n]+1.0*(sec[1].x-x)/(1.0*v)*sum[n]+eps));
            continue;
        }
        if(st==n) {
            printf("%.0lf\n",floor(bs+cr[n][1]+1.0*(x-sec[n].x)/(1.0*v)*sum[n]+eps));
            continue;
        }
        f[st][st][0]=f[st][st][1]=1.0*(x-sec[st].x)/(1.0*v)*sum[n];
        f[st+1][st+1][0]=f[st+1][st+1][1]=1.0*(sec[st+1].x-x)/(1.0*v)*sum[n];
        min0[st]=min1[st]=f[st][st][0];
        min0[st+1]=min1[st+1]=f[st+1][st+1][0];
        for(int i=2;i<=n;++i)
            for(int j=max(1,st-i+1);j<=st+1 && i+j-1<=n;++j)
            {
                int l=j,r=j+i-1;
                double pre=sum[n]-sum[r]+sum[l-1];
                f[l][r][0]=min0[r]+cr[r][l]+tme(r,l)*pre;
                f[l][r][1]=min1[l]+cl[l][r]+tme(r,l)*pre;
                min0 [r] = min (min0 [r], b [l] [s] [ 1 ] - cr [s] [l]);
                min1[l]=min(min1[l],f[l][r][0]-cl[l][r]);
                //cout<<l<<" "<<r<<" "<<f[l][r][0]<<" "<<f[l][r][1]<<endl;
            }
        printf("%.0lf\n",floor(min(f[1][n][0],f[1][n][1])+bs+eps));
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/w19567/p/11314962.html