1、http://poj.org/problem?id=1991
2、题目大意:
Bessie要交作业,现在知道每个教师的位置,假设都位于X轴上,每份作业都有一个最早交的时间,知道公交车站位于坐标B的对面,假设他每走一个单位耗费时间是1,求他交完作业到达公交车站那最少的时间是什么?
3、题目分析
这道题目乍一看好像有思路,这跟吃草坪的拿到题目很像,但仔细已考虑就发现不是那么回事,现在我们不仅规定了起始点,而且规定了结束的位置,假如我们还是用dp[i][j][0],dp[i][j][1]来表示状态,那么我们能够求出1-n都交完作业的最少时间,但是不能够确定当前是在哪个位置,因为最后我们还要加上从当前位置到公交车站的距离,想了好久发现都不能实现,搜了一下别人的解题报告,发现了一种非常巧妙的解题思路
我们将dp[i][j][0]表示为i-j区间尚未完成交作业的最少时间,其中0代表只交了i作业,dp[i][j][1]同理就是只交了j作业,那么我们将很容易想出来,这是由大区间逐渐推出小区间的一个过程,最终的dp[i][i][0]和dp[i][i][1]就代表停留在i位置的最少时间,最后再加上i-B的距离就是到达公交车站的时间
dp[1][n][0]=max(a[1].x,a[1].t),这个很好理解,在1-n区间内只交了1作业
dp[1][n][1]=max(a[n].x,a[n].t),这个很好理解,在1-n区间内只交了n作业
4、题目:
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 1010 | Accepted: 444 |
Description
Input
Output
Sample Input
4 10 3 8 9 4 21 3 16 8 12
Sample Output
22
Hint
Time Action 0 Bessie walks to the classrooms 8 meters down the hall (at 8m) 8 Bessie waits 1 second 9 Bessie turns in the first set of homework 9 Bessie waits 3 seconds, thinking about cool hay in the summertime 12 Bessie turns in the other homework for this location 12 Bessie walks back to the classroom 4 meters down the hall (at 4m) 16 Bessie waits 5 seconds, thinking of a handsome bull she once met 21 Bessie turns in her homework 21 Bessie walks back to the classroom 1 meters down the hall (at 3m) 22 Bessie turns in her homework 22 Bessie exits, since this also the location of the bus exit Thus, Bessie can leave at time 22. No better schedule exists.
Source
5、AC代码:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define N 1005 #define INF 10000005 int dp[N][N][2]; struct node { int x; int t; } a[N]; int cmp(node a,node b) { if(a.x==b.x) return a.t<b.t; return a.x<b.x; } void DP(int n) { //大区间推出小区间 dp[1][n][0] = max(a[1].x, a[1].t); dp[1][n][1] = max(a[n].x, a[n].t); for(int d=n-2; d>=0; d--) { for(int i=1; i+d<=n; i++) { int s=i; int e=i+d; dp[s][e][0]=INF; // dp[s][e][0]=min(dp[s][e][0],max(dp[s-1][e][0]+a[s].x-a[s-1].x,a[s].t)); // dp[s][e][0]=min(dp[s][e][0],max(dp[s][e+1][1]+a[e+1].x-a[e].x,a[e].t)); // dp[s][e][1]=min(dp[s][e][1],max(dp[s][e+1][0]+a[e].x-a[s].x,a[e].t)); // dp[s][e][1]=min(dp[s][e][1],max(dp[s-1][e][1]+a[e].x-a[s].x,a[s].t)); if(s-1>0) { dp[s][e][0]=min(dp[s][e][0],dp[s-1][e][0]+a[s].x-a[s-1].x); } if(e+1<=n) { dp[s][e][0]=min(dp[s][e][0],dp[s][e+1][1]+a[e+1].x-a[s].x); } if(dp[s][e][0]<a[s].t) dp[s][e][0]=a[s].t; dp[s][e][1]=INF; if(e+1<=n) { dp[s][e][1]=min(dp[s][e][1],dp[s][e+1][1]+a[e+1].x-a[e].x); } if(s-1>0) { dp[s][e][1]=min(dp[s][e][1],dp[s-1][e][0]+a[e].x-a[s-1].x); } if(dp[s][e][1]<a[e].t) dp[s][e][1]=a[e].t; } } } int main() { int C,H,B; 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,cmp); // for(int i=1;i<=C;i++) // printf("***%d %d\n",a[i].x,a[i].t); a[0].x=0; a[0].t=0; DP(C); int ans=INF; for(int i=1; i<=C; i++) { ans=min(min(dp[i][i][0]+abs(a[i].x-B),dp[i][i][1]+abs(a[i].x-B)),ans); } printf("%d\n",ans); return 0; }