zoukankan      html  css  js  c++  java
  • 动态规划——独立任务最优调度(Independent Task Scheduling)

    题目链接

    题目描述

    用2 台处理机A 和B 处理n 个作业。设第i 个作业交给机器A 处理时需要时间i a ,若由机器B 来处理,则需要时间i b 。由于各作业的特点和机器的性能关系,很可能对于某些i,有ai >=bi,而对于某些j,j≠i,有aj < bj 。既不能将一个作业分开由2 台机器处理,也没有一台机器能同时处理2 个作业。设计一个动态规划算法,使得这2 台机器处理完这n个作业的时间最短(从任何一台机器开工到最后一台机器停工的总时间)。研究一个实例: (a1,a2,a3,a4,a5,a6)=(2,5,7,10,5,2);(b1,b2,b3,b4,b5,b6)=(3,8,4,11,3,4)。 对于给定的2 台处理机A 和B处理n 个作业,找出一个最优调度方案,使2台机器处理完这n 个作业的时间最短。

    输入

    的第1行是1个正整数n<=200, 表示要处理n个作业。 接下来的2行中,每行有n 个正整数,分别表示处理机A 和B 处理第i 个作业需要的处理时间。

    输出

    最短处理时间

    样例输入

    复制
    6
    2 5 7 10 5 2
    3 8 4 11 3 4

    样例输出

    15

    题解:
    这道题是说有N个作业可以在两个机器A,B上操作,同一个作业在A,B上不能同时进行,并且在A,B上的操作时间不同,所以我们要考虑从1~n个作业,哪些在A上,哪些在B上操作,所需要的时间最短。
    用动态规划的思想,我们做这样的思考:当操作第i个作业时,我们选A还是B机器?在题目的要求下,我们就需要根据i-1的操作和i操作之间的关联来解题了。

    先定义变量:a[i]-操作i在机器A上的时间
    b[i]-操作i在机器B上的时间
    f[i][j]操作到第i个作业时,在A机器已经花费j时间的情况下,找到b机器操作的时间

    这道题可以这样来做:当我们全部选A操作的时候,时间上限为a[i]的和,即suma,所以作业从1~n在A上操作的时间都不会超过suma。
    我们就可以在A机器操作时间0<=j<=suma的范围内,操做到第i个操作时,在B机器上所花的最短时间。
    最短时间:1.当a[i] >j时,f[i][j]=f[i-1][j]+b[i];即在操作到i作业时,A机器所花费的时间大于j,所以不能再A机器上操作了,所以这时应该选择B机器,就要找在操作到i-1作业时,
    A机器已经花费j时间的情况下,B机器已经操作的时间f[i-1][j],然后在i操作时选了B,就是f[i-1][j]+b[i]了。
    2.当a[i]<=j时,f[i][j]=min(f[i-1][j-a[i]],f[i-1][j]+b[i]);,可能选A机器,可能选B机器,如果选A机器,接要找在操作到i-1作业,A已经花费的时间为j-a[i]时B机器的时间f[i-1][j-a[i]],因为没选B,所以这时候f[i][j]的时间与f[i-1][j-a[i]]相等。

    当操作到第n个操作时,从A机器操作时间0~suma的情况下,各个B机器操作的最短时间就找出来了。我们要在A机器花费时间0~suma的时间段里,逐一比较A,B机器的时间,会按最长的时间选出A,B机器的代表,
    再在这suma个时间代表中选出最小的哪一个作为最短花时间。
    代码如下:
    #include<bits/stdc++.h>
    using namespace std;
    #define MAX 201
    int a[MAX];//a[i],A机器 处理i作业花费时间 
    int b[MAX];//b[i],B机器 处理i作业花费时间 
    int f[MAX][10000];// f[i][j],在处理i作业时A机器花费j时间的情况下B机器花费的最小时间 
    int suma=0;//如果所有作业全部由A机器处理,最大时间限制 
    int min(int x,int y)
    {
        return x<y?x:y;
    }
    int max(int x,int y)
    {
        return x>y?x:y;
    }
    int dealWith(int n)
    {
    
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<=suma;j++)
            {
                if(a[i]<=j)
                {
                    f[i][j]=min(f[i-1][j-a[i]],f[i-1][j]+b[i]);
                }
                else
                {
                    f[i][j]=f[i-1][j]+b[i];
                }
        
                
            }
        
        }
        int m=99999;
        for(int j=1;j<=suma;j++)
        {
            int t;
            t=max(j,f[n][j]);
            m=min(m,t);    
        
        }
        
        return m;
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            suma+=a[i]; 
        } 
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&b[i]);
        }
        int m=dealWith(n); 
        printf("%d
    ",m);
        return 0;
     } 
     
  • 相关阅读:
    poj 1262 地板覆盖问题
    混合图 (Standard IO)
    matrix
    麻将 (Standard IO)
    C#多线程编程之:异步事件调用
    使用线程池与专用线程
    C#多线程编程之:Timer(定时器)使用示例
    C#多线程编程之:异步方法调用
    WCF 快速入门
    c#实现每隔一段时间执行代码(多线程)
  • 原文地址:https://www.cnblogs.com/ellen-mylife/p/11010625.html
Copyright © 2011-2022 走看看