标签:abs const return font == cout 标记 node name
https://vjudge.net/problem/UVA-1336
显然最佳的移动方式一定是向左走一段,向右走一段,再向左走一段,再向右走一段......(或者反过来)
无论如何中间的会最先被修理好,所以考虑区间dp
$f_{i,j,0/1}$表示修理好了$i\rightarrow j$时,所用的最小费用(注意费用提前计算)
预处理处$cl_{i,j}(i\leq j)$表示从$i$出发修理到$j$的费用
$cr_{i,j}(i\geq j)$从$i$出发修理到$j$的费用
然后就是转移了(其实还是很好想的),由于决策集合不会变小,所以可以用一个标记记录一下最小值,$O(1)$转移
#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]=min1[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],f[l][r][1]-cr[r][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; }
标签:abs const return font == cout 标记 node name
原文地址:https://www.cnblogs.com/w19567/p/11314962.html