【USACO】2004 Open Turning in Homework 提交作业

来源:互联网 发布:河北seo按效果付费 编辑:程序博客网 时间:2024/06/06 07:06

Turning in Homework 提交作业


  • Description

贝西在哞哞大学选修了C门课,她要把这些课的作业交给老师,然后去车站和同学们一 起回家。老师们在办公室里,办公室要等他们下课后才开,第i门课的办公室在Ti时刻后开放。
所有的办公室都在一条走廊上,这条走廊长H米,一开始贝西在走廊的最西边,第i门课 的办公室距离贝西的长度为Xi,车站距离贝西的长度为B。
贝西可在走廊上自由行走,每时刻可以向东或者向西移动一单位的距离,也可以选择在 任何地方暂停。贝西如果走到办公室所处的位置,而且这间办公室已经开门了的话,就可以 把作业交掉,不用花时间在走进办公室上。
请帮助贝西确定交完所有作业,再走到车站的最短时间。

  • Input Format

第一行:三个整数C,H和B,1 ≤ C ≤ 1000,1 ≤ H ≤ 1000,0 ≤ B ≤ H
第二行到C + 1行:每行两个整数,表示Xi和Ti,0 ≤ Xi ≤ H,0 ≤ Ti ≤ 10000

  • Output Format

第一行:单个整数,表示贝西交完作业后走到车站的最短时间

  • Sample Input

4 10 3
8 9
4 21
3 16
8 12

  • Sample Output

22

  • Hint

时刻 贝西的行动

0 走向坐标为8的教室
8 等待
9 交第一本作业,等待
12 在原位置交第二本作业
12 走向坐标为4的教室
16 等待
21 交一本作业
21 走向坐标为3的教室
22 交一本作业
22 贝西正好到车站了,结束


  • 分析

看到这道题第一反应就是设F[i][j][0/1] 表示完成了i~j这段区间的作业,然后走到了i(0)或j(1)。但是这个方程得出的答案最后贝西只能在1或n的位置上,可是有可能最后走到中间某个位置再走到终点比起前两者更优。
所以我们稍微修改一下方程的定义,令F[i][j][0/1] 表示除了i~j这段区间没完成其他的都完成了,然后现在要完成i(0)或j(1)的最短时间。这样子就是从一个大区间F[1][n] 推到F[i][i] ,最后我们就能比较从哪个位置前往终点最优了。
转移方程跟第一种想法差不多,只不过第一种想法是用小区间推大区间,所以会导致答案不能保证最优。(方程详见代码)


#include <queue>#include <stack>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int C,H,B,F[1005][1005][2],Ans=1<<30;struct Data{int x,t;}A[1005];inline bool cmp(const Data&a,const Data&b){return a.x<b.x;}int main(){    freopen("in.txt","r",stdin);    freopen("out.txt","w",stdout);    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+1+C,cmp);    memset(F,127/2,sizeof(F));    F[1][C][0]=max(A[1].x,A[1].t); F[1][C][1]=max(A[C].x,A[C].t);    for (int i=1;i<=C;i++){        for (int j=C;j>=i;j--){            F[i][j][0]=min(F[i][j][0],max(F[i-1][j][0]+A[i].x-A[i-1].x,A[i].t));            F[i][j][0]=min(F[i][j][0],max(F[i][j+1][1]+A[j+1].x-A[i].x,A[i].t));            F[i][j][1]=min(F[i][j][1],max(F[i-1][j][0]+A[j].x-A[i-1].x,A[j].t));            F[i][j][1]=min(F[i][j][1],max(F[i][j+1][1]+A[j+1].x-A[j].x,A[j].t));                    }    }    for (int i=1;i<=C;i++)        Ans=min(Ans,min(F[i][i][0],F[i][i][1])+abs(B-A[i].x));    printf("%d",Ans);    fclose(stdin); fclose(stdout);    return 0;}
0 0
原创粉丝点击