Fixing the Great Wall
题意:修长城,初始位置为fp,n个点要修,初始每个点修缮费用为ci,单位时间增加费用di,问最少费用。
区间dp
和送外卖那个差不多~
有一个细节,输入不加!=EOF的话会超时(虽然题目说了以00结束)
1 #include <cstdio> 2 #include <bits/stdc++.h> 3 using namespace std; 4 const int maxn=1005; 5 struct node 6 { 7 int pos,c,d; 8 node(int pos=0,int c=0,int d=0):pos(pos),c(c),d(d){} 9 bool operator <(const node &x) const 10 { 11 return pos<x.pos; 12 } 13 }p[maxn]; 14 int sum[maxn]; 15 double dp[maxn][maxn][2]; 16 17 int main() 18 { 19 int n,v,fp; 20 while(scanf("%d%d%d",&n,&v,&fp)!=EOF&&(n||v||fp)) 21 { 22 for(int i=0;i<n;i++) 23 scanf("%d%d%d",&p[i].pos,&p[i].c,&p[i].d); 24 p[n].pos=fp;p[n].c=0;p[n].d=0; 25 sort(p,p+n+1); 26 int w=lower_bound(p,p+n+1,node(fp,0,0))-p; 27 sum[0]=p[0].d; 28 for(int i=1;i<=n;i++) sum[i]=sum[i-1]+p[i].d; 29 //memset(dp,0x3f3f3f3f,sizeof(dp)); 30 for(int i=0;i<=n;i++) 31 for(int j=i;j<=n;j++) dp[i][j][0]=dp[i][j][1]=0x3f3f3f3f; 32 dp[w][w][0]=dp[w][w][1]=0; 33 for(int i=w;i>=0;i--) 34 for(int j=w;j<=n;j++) 35 { 36 double ss=sum[i-1]+sum[n]-sum[j]; 37 if(i!=0) //往左 38 { 39 //从左到左 40 double t=1.0*(p[i].pos-p[i-1].pos)/v; 41 dp[i-1][j][0]=min(dp[i-1][j][0],dp[i][j][0]+p[i-1].c+t*ss); 42 //从右到左 43 t=1.0*(p[j].pos-p[i-1].pos)/v; 44 dp[i-1][j][0]=min(dp[i-1][j][0],dp[i][j][1]+p[i-1].c+t*ss); 45 } 46 if(j!=n) //往右 47 { 48 //从右到右 49 double t=1.0*(p[j+1].pos-p[j].pos)/v; 50 dp[i][j+1][1]=min(dp[i][j+1][1],dp[i][j][1]+p[j+1].c+ss*t); 51 //从左到右 52 t=1.0*(p[j+1].pos-p[i].pos)/v; 53 dp[i][j+1][1]=min(dp[i][j+1][1],dp[i][j][0]+p[j+1].c+ss*t); 54 } 55 } 56 int ans=min(dp[0][n][0],dp[0][n][1]); 57 printf("%d ",ans); 58 } 59 return 0; 60 }