BZOJ 3379: [Usaco2004 Open]Turning in Homework 交作業
阿新 • • 發佈:2017-09-09
() sam sca operator 計算 images its main src
8 9
4 21
3 16
8 12
Description
貝茜有C(1≤C≤1000)門科目的作業要上交,之後她要去坐巴士和奶牛同學回家. 每門科目的老師所在的教室排列在一條長為H(1≤H≤1000)的走廊上,他們只在課後接收作業.交作業不需要時間.貝茜現在在位置0,她會告訴你每個教室所在的位置,以及走廊出口的位置.她每走1個單位的路程,就要用1秒.她希望你計算最快多久以後她能交完作業並到達出口.Input
第1行輸入三個整數C,H,B,B是出口的位置.之後C行每行輸入兩個整數,分別表示一個老師所在的教室和他的下課時間.Output
貝茜最早能夠到達出口的時間.Sample Input
4 10 38 9
4 21
3 16
8 12
Sample Output
22
解法:一個經典的DP。令dp[i][j][0/1] 表示除了i~j這段區間沒完成其他的都完成了,然後現在要完成i(0)或j(1)的最短時間。這樣子就是從一個大區間F[1][n] 推到F[i][i] ,最後我們就能比較從哪個位置前往終點最優了。
轉移方程跟第一種想法差不多,只不過第一種想法是用小區間推大區間,所以會導致答案不能保證最優。
#include <bits/stdc++.h> using namespace std; int C, H, B; int dp[1005][1005][2]; struct node{ int x, t; bool operator<(const node &rhs)const{ return x<rhs.x; } }A[1005]; int main() { scanf("%d %d %d", &C,&H,&B); for(int i=1; i<=C; i++){ scanf("%d %d", &A[i].x, &A[i].t); } sort(A+1,A+C+1); memset(dp, 0x7f, sizeof(dp)); dp[1][C][0] = max(A[1].x, A[1].t); dp[1][C][1] = max(A[C].x, A[C].t); for(int i=1; i<=C; i++){ for(int j=C; j>=1; j--){ dp[i][j][0] = min(dp[i][j][0], max(dp[i-1][j][0]+A[i].x-A[i-1].x, A[i].t)); dp[i][j][0] = min(dp[i][j][0], max(dp[i][j+1][1]+A[j+1].x-A[i].x, A[i].t)); dp[i][j][1] = min(dp[i][j][1], max(dp[i-1][j][0]+A[j].x-A[i-1].x, A[j].t)); dp[i][j][1] = min(dp[i][j][1], max(dp[i][j+1][1]+A[j+1].x-A[j].x, A[j].t)); } } int ans = INT_MAX; for(int i=1; i<=C; i++){ ans = min(ans, min(dp[i][i][0], dp[i][i][1])+abs(B-A[i].x)); } printf("%d\n", ans); return 0; }
BZOJ 3379: [Usaco2004 Open]Turning in Homework 交作業