POJ 1337 A Lazy Worker

题意:

有一个懒工人,他要完成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<<30
using 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;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值