POJ 1991 Turning in Homework 区间DP

时空隧道


好久没写blog了….
主要是pku停电太久了……
poj一直在挂…..


题目大意:
Bessie要去交作业,起点为原点,教室坐标都在x轴上,并且每个教室都有一个最早交作业时间,问Bessie交完所有作业并且到达终点B的最早到达时间


分析:
很明显是DP….但是状态和转移比较难想….
f[i][j][0]代表pos[i]~pos[j]这一段区间的作业还没交并且先交pos[i]的最早到达时间
f[i][j][1]就不用说了…..
当我们有pos[i]~pos[j]这一连续区间未交作业时,我们先交i或j很明显是比先交k要优的……(i < k < j)这个很重要O(≧口≦)O啊~~~
然后感觉转移就呼之欲出了….>_<…


代码如下:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define Min(a,b,c) min(a,min(b,c))
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=1000+5;
int n,h,b,f[maxn][maxn][2];
struct M{
    int pos,tim;
    friend bool operator < (M x,M y){
        if(x.pos==y.pos)
            return x.tim<y.tim;
        return x.pos<y.pos;
    }
}s[maxn];
signed main(void){
    scanf("%d%d%d",&n,&h,&b);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&s[i].pos,&s[i].tim);
    sort(s+1,s+n+1);
    memset(f,inf,sizeof(f));
    f[1][n][0]=max(s[1].pos,s[1].tim);
    f[1][n][1]=max(s[n].pos,s[n].tim);
    for(int i=1;i<=n;i++)
        for(int j=n;j>=1;j--){
            f[i][j][0]=min(max(f[i-1][j][0]+s[i].pos-s[i-1].pos,s[i].tim),f[i][j][0]);
            f[i][j][0]=min(max(f[i][j+1][1]+s[j+1].pos-s[i].pos,s[i].tim),f[i][j][0]);
            f[i][j][1]=min(max(f[i-1][j][0]+s[j].pos-s[i-1].pos,s[j].tim),f[i][j][1]);
            f[i][j][1]=min(max(f[i][j+1][1]+s[j+1].pos-s[j].pos,s[j].tim),f[i][j][1]);
        }
    int ans=inf;
    for(int i=1;i<=n;i++)
        ans=Min(ans,f[i][i][0]+abs(s[i].pos-b),f[i][i][1]+abs(s[i].pos-b));
    cout<<ans<<endl;
    return 0;
}

by >_< neighthorn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值