ZOJ-3331-Process the Tasks【7th浙江省赛】【双塔dp】【好题】

86 篇文章 9 订阅
56 篇文章 0 订阅

ZOJ-3331-Process the Tasks


                    Time Limit: 1 Second      Memory Limit: 32768 KB

There are two machines A and B. There are n tasks, namely task 1, task 2, …, task n. You must assign each task to one machine to process it. There are some facts you must know and comply with:

You must assign each task to only one machine to process.
At any time, a machine can process at most one task.
Task i (0 < i < n) can be processed if and only if each task j (0 < j < i) has been processed or processing.
If a task is processing on one machine, it cannot be interrupted.
You want to do finish all the tasks as soon as possible.

Input

There are multiple test cases. The first line of the input is an integer T (0 < T < 1000) indicating the number of test cases. Then T test cases follow. Each test case starts with an integer n (0 < n < 100). The ith line of the next n lines contains two integers tA, tB (0 < tA, tB < 100), giving the time to process the ith task by machine A and machine B.

Output

For each test case, output the earliest time when all the tasks have been processed.

Sample Input
4
1
1 2
2
1 2
2 1
2
1 2
90 95
3
1 3
1 3
1 3

Sample Output
1
1
90
3

Hints
Test case 1: Let machine A process task 1.
Test case 2: Let machine A process task 1 and at the same time let machine B process task 2.
Test case 3: Let machine B process task 1 and at the same time let machine A process task 2.
Test case 4: Let machine A process all the tasks.

题目链接:ZOJ-3331

题目大意:有两台机器,然后有一些项目需要完成,这些项目必须按照顺序来执行,第i个项目能执行的前提条件是i-1个项目执行完成或正在执行。

题目思路:这是第一次接触双塔dp。

首先可以将问题转化为两个塔,塔的高度为在该机器上完成的项目的总时间。

存在两种情况:

  1. 工作加在较高的塔上,此时高度差增加,需注意低塔也要增加空闲值(因为那段时间还在处理i-1任务,i任务还没有开始,i+1不可能进行)

  2. 工作加在较低的塔上,①低塔变为高塔 ② 低塔仍为低塔

以A塔为高塔为例:

这里写图片描述

ps:高度差 j 为A塔高度减去B塔

以下是代码:

#include <bits/stdc++.h>
#define mst(a) memset(a,0,sizeof (a))
#define FOR(i,n) for (int i = 0; i < n; i++)
#define INF 1e9
#define eps 1e-10
using namespace std;

typedef long long ll;
int dp[105][200]; //前i项任务,两个机器时间差为j,两塔中较高塔的高度。 
int ta[105],tb[105];
int main(){
    int t;
    cin >> t;
    while(t--)
    {
        int offset = 100;  //时间差可为正可为负,故增加offset保证值为正
        //输入 
        int n;
        cin >> n;
        for (int i = 1; i <= n; i++)
        {
            cin >> ta[i] >> tb[i]; 
        }

        for (int i = 0; i <= n; i++)
            for (int j = 0; j <= 200; j++) dp[i][j] = INF;
        dp[0][0 + offset] = 0; //没有任务时候,为0       
        for (int i = 1; i <= n; i++)  //第i项任务 
        {
            for (int j = -99; j <= 99; j++) // 时间差 
            {
                if (dp[i - 1][j + offset] == INF) continue;
                if (j < 0)  //B塔较高              
                {
                    dp[i][-tb[i] + offset] = min(dp[i][-tb[i] + offset],dp[i - 1][j + offset] + tb[i]);  //第i项任务放在B塔上
                    dp[i][j + ta[i] + offset] = min(dp[i][j + ta[i] + offset],dp[i - 1][j + offset] + max(0,j + ta[i])); //第i项任务放在A塔上,①低塔变成高塔 + j + ta[i];②低塔仍为低塔 + 0(利用了空闲时间,高塔高度不变即dp值不变);                                              
                }  
                else  //A塔较高  同理 
                {
                    dp[i][ta[i] + offset] = min(dp[i][ta[i] + offset], dp[i - 1][j + offset] + ta[i]);
                    dp[i][j - tb[i] + offset] = min(dp[i][j - tb[i] + offset], dp[i - 1][j + offset] + max(0,tb[i] - j));
                } 
            }
        }
        int ans = INF;
        for (int i = -99; i <= 99; i++) ans = min(dp[n][i + offset],ans);
        cout << ans << endl;
    } 
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值