poj 1991 Turning in Homework dp

这个可以证明必须从两边的任务开始交起,因为中间交的任务可以后面经过的时候再交,所以就变成了一个n*n的dp。

 

#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>

using namespace std;

const int maxn=1e3+9;

int dp[maxn][maxn][2];

struct D

{

    int x,t;

    bool operator <(const D & xx) const

    {

        return x<xx.x;

    }

}a[maxn];



int ff(int x)

{

    if(x<0) return -x;

    return x;

}



int main()

{

    int n,m,b;

    while(scanf("%d %d %d",&n,&m,&b)!=EOF)

    {

        for(int i=1;i<=n;i++)

        scanf("%d %d",&a[i].x,&a[i].t);

        sort(a+1,a+1+n);

        memset(dp,50,sizeof(dp));

        dp[0][n+1][0]=0;

        for(int k=0;k<n;k++)

        for(int i=0;i<=k;i++)

        {

            int tmp=max(dp[i][n+1-(k-i)][0]+a[i+1].x-a[i].x,a[i+1].t);

            dp[i+1][n+1-(k-i)][0]=min(dp[i+1][n+1-(k-i)][0],tmp);



            tmp=max(dp[i][n+1-(k-i)][0]+a[n+1-(k-i)-1].x-a[i].x,a[n+1-(k-i)-1].t);

            dp[i][n+1-(k-i)-1][1]=min(dp[i][n+1-(k-i)-1][1],tmp);



            tmp=max(dp[i][n+1-(k-i)][1]+a[n+1-(k-i)].x-a[n+1-(k-i)-1].x,a[n+1-(k-i)-1].t);

            dp[i][n+1-(k-i)-1][1]=min(dp[i][n+1-(k-i)-1][1],tmp);



            tmp=max(dp[i][n+1-(k-i)][1]+a[n+1-(k-i)].x-a[i+1].x,a[i+1].t);

            dp[i+1][n+1-(k-i)][0]=min(dp[i+1][n+1-(k-i)][0],tmp);

        }

        int ans=1e10;

        for(int i=0;i<=n;i++)

        {

            ans=min(ans,dp[i][i+1][0]+ff(b-a[i].x));

            ans=min(ans,dp[i][i+1][1]+ff(b-a[i+1].x));

        }

        cout<<ans<<endl;

    }

    return 0;

}


 

 

你可能感兴趣的:(home)