POJ 1337 A Lazy Worker

来源:互联网 发布:淘宝广告商品漏洞 编辑:程序博客网 时间:2024/06/07 22:58

题意:

有一个懒工人,他要完成n个任务。每个任务都需要花费时间ti并且在[ai,bi]这个时间范围内完成。对于某个时间点如果有工作可以完成,那么他必须选择一个来完成,工作一旦开始就不能被打断。当然这个工人很懒,所以他希望他工作的时间越短越好。


解题思路:

首先我们可以预处理处对于某个时间点,工人可以完成的任务有哪些。当一个任务在时间点t满足 ai <= t  && t + ti <= bi时就说明该任务可以在时间点t完成。

这样预处理后就很容易想用DP来解决此问题了。用dp[t] 表示从时间点t开始的最少工作时间。如果有任务可以做 那么就由做了这个任务之后的状态来跟新  dp[t] = min(dp[t], dp[t+ti] + ti); 否则就有 dp[t] = dp[t+1];这样从后往前dp一遍就得到解了。

//by dreameracm#include <cstdio>#include <algorithm>#include <vector>#define INF 1<<30using namespace std;struct node{    int x,y,z;};node p[1005];vector<int> can[500];int dp[500];int main(){    int t,n;    scanf("%d",&t);    while(t--)    {        int mint=1000,maxt=0;        scanf("%d",&n);        for (int i = 0; i < n; i++)        {            scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].z);            mint=min(mint,p[i].y);//更新最小时间            maxt=max(maxt,p[i].z);//更新最大时间        }        for (int i = mint; i < maxt; i++)        {            can[i].clear();            for (int j = 0; j < n; j++)            {                if (p[j].y<=i && i + p[j].x <= p[j].z)//计算每个时间点可以做的任务                {                    can[i].push_back(j);                }            }        }        dp[maxt] = 0;//初始化最大时间的解        for (int i = maxt-1; i >= mint; i--)        {                        if(can[i].empty())//没有任务可以做时的情况            {                dp[i] = dp[i+1];            }            else            {                dp[i] = INF;                for (int j = 0; j < (int)can[i].size(); j++)//用法每一个任务更新dp[i]的值                {                    dp[i] = min(dp[i],dp[i+p[can[i][j]].x]+p[can[i][j]].x);                }            }        }        printf("%d\n",dp[mint]);    }    return 0;}