题意:
一个人要从如果干个地方拿货,每个地方的货物是有存在时间的,到了某个时间之后就会消失。
按照位置从左到右给出货物的位置以及生存时间,这个人选择一个最优的位置出发,问拿完货物的最少时间。
思路:
首先确定最优位置就是生存时间最少的货物的位置。
区间dp,dp[i][j][0]和dp[i][j][1]分别表示取完i到j这个区间的所有货物之后在左边和在右边的最少时间。
转移看具体代码。
min这个函数貌似非常耗时,t了5发define了一个mi就过了。
代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #define mi(a,b) (a) >= (b) ? (b) : (a) 5 using namespace std; 6 const int N = 1e4 + 5; 7 const int inf = 0x3f3f3f3f; 8 int dp[N][N][2]; 9 10 struct node 11 { 12 int p,d; 13 node(){}; 14 node(int x,int y):p(x),d(y){}; 15 }a[N]; 16 int main() 17 { 18 int n; 19 while (scanf("%d",&n) == 1) 20 { 21 memset(dp,inf,sizeof(dp)); 22 for (int i = 1;i <= n;i++) 23 { 24 scanf("%d%d",&a[i].p,&a[i].d); 25 } 26 int k = 1; 27 for (int i = 1;i <= n;i++) 28 { 29 if (a[i].d < a[k].d) 30 { 31 k = i; 32 } 33 } 34 dp[k][k][0] = dp[k][k][1] = 0; 35 for (int i = k;i >= 1;i--) 36 { 37 for (int j = k;j <= n;j++) 38 { 39 if (i == j) continue; 40 int &x = dp[i][j][0]; 41 int &y = dp[i][j][1]; 42 x = mi(x,a[i+1].p - a[i].p + dp[i+1][j][0]); 43 x = mi(x,a[j].p - a[i].p + dp[i+1][j][1]); 44 y = mi(a[j].p - a[j-1].p + dp[i][j-1][1],y); 45 y = mi(y,a[j].p - a[i].p + dp[i][j-1][0]); 46 if (x >= a[i].d) x = inf; 47 if (y >= a[j].d) y = inf; 48 } 49 } 50 int ans = min(dp[1][n][1],dp[1][n][0]); 51 if (ans == inf) printf("No solution "); 52 else printf("%d ",ans); 53 } 54 return 0; 55 } 56 /* 57 5 58 1 3 3 1 5 8 59 8 19 10 15 60 5 1 5 2 1 3 4 4 2 5 3 61 */