zoukankan      html  css  js  c++  java
  • 一本通1606【 例 1】任务安排 1

    1606:【 例 1】任务安排 1

    时间限制: 1000 ms         内存限制: 524288 KB

    【题目描述】

    有 N 个任务排成一个序列在一台机器上等待执行,它们的顺序不得改变。机器会把这 N 个任务分成若干批,每一批包含连续的若干个任务。从时刻 0 开始,任务被分批加工,执行第i个任务所需的时间是 Ti。另外,在每批任务开始前,机器需要 S 的启动时间,故执行一批任务所需的时间是启动时间 S 加上每个任务所需时间之和。

    一个任务执行后,将在机器中稍作等待,直至该批任务全部执行完毕。也就是说,同一批任务将在同一时刻完成。每个任务的费用是它的完成时刻乘以一个费用系数 Ci 。

    请为机器规划一个分组方案,使得总费用最小。

    【输入】

    第一行是 N。第二行是 S

    下面 N 行每行有一对正整数,分别为 Ti和 Ci ,表示第 i 个任务单独完成所需的时间是 Ti 及其费用系数 Ci 。

    【输出】

    一个数,最小的总费用。

    【输入样例】

    5
    1
    1 3
    3 2
    4 3
    2 3
    1 4

    【输出样例】

    153

    【提示】

    样例说明:

    分组方案为{1,2},{3},{4,5},则完成时间为 {5,5,10,14,14},费用 C={15,10,30,42,56},总费用为 153。

    数据范围与提示:

    对于全部数据,1N5000,0S50,1Ti,Ci100

    sol:n3 应该很简单,dp[i][j]表示到第i个任务,分了几段(因为时间是有后效性的,处理起来很蛋疼

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    inline ll read()
    {
        ll s=0;
        bool f=0;
        char ch=' ';
        while(!isdigit(ch))
        {
            f|=(ch=='-'); ch=getchar();
        }
        while(isdigit(ch))
        {
            s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
        }
        return (f)?(-s):(s);
    }
    #define R(x) x=read()
    inline void write(ll x)
    {
        if(x<0)
        {
            putchar('-'); x=-x;
        }
        if(x<10)
        {
            putchar(x+'0');    return;
        }
        write(x/10);
        putchar((x%10)+'0');
        return;
    }
    #define W(x) write(x),putchar(' ')
    #define Wl(x) write(x),putchar('
    ')
    const int N=5005;
    const ll inf=0x7fffffffff;
    int n,S;
    int Time[N],Cost[N],Time_Qzh[N],Cost_Qzh[N];
    ll dp[N][N];
    int main()
    {
        int i,j,k;
        R(n); R(S);
        for(i=1;i<=n;i++)
        {
            Time_Qzh[i]=Time_Qzh[i-1]+(Time[i]=read());
            Cost_Qzh[i]=Cost_Qzh[i-1]+(Cost[i]=read());
        }
        memset(dp,63,sizeof dp);
        dp[0][0]=0;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=i;j++)
            {
                for(k=j-1;k<=i-1;k++)
                {
                    dp[i][j]=min(dp[i][j],dp[k][j-1]+1ll*(Time_Qzh[i]+S*j)*(Cost_Qzh[i]-Cost_Qzh[k]));
                }
            }
        }
        ll ans=inf;
        for(i=1;i<=n;i++) ans=min(ans,dp[n][i]);
        Wl(ans);
        return 0;
    }
    /*
    input
    5
    1
    1 3
    3 2
    4 3
    2 3
    1 4
    output
    153
    */
    n^3做法

    绞尽脑汁想n2dp做法,肯定是dp[i]表示前i个任务的最小权值,但这样是不行的

    后来是这样的(并不知道dp[i]表示什么)

    如果j~i是一段的

    1):j~n之间要多S的时间 S*(Cost[n]-Cost[j-1]) ----> dp[i]

    2):i到j之间的任务结束时间是 Time[i]  Time[i]*(Cost[i]-Cost[j-1]) ---->dp[i]

    #include <bits/stdc++.h>
    using namespace std;
    typedef int ll;
    inline ll read()
    {
        ll s=0;
        bool f=0;
        char ch=' ';
        while(!isdigit(ch))
        {
            f|=(ch=='-'); ch=getchar();
        }
        while(isdigit(ch))
        {
            s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
        }
        return (f)?(-s):(s);
    }
    #define R(x) x=read()
    inline void write(ll x)
    {
        if(x<0)
        {
            putchar('-'); x=-x;
        }
        if(x<10)
        {
            putchar(x+'0');    return;
        }
        write(x/10);
        putchar((x%10)+'0');
        return;
    }
    #define W(x) write(x),putchar(' ')
    #define Wl(x) write(x),putchar('
    ')
    const int N=5005;
    int n,S,dp[N];
    ll Time[N],Cost[N];
    int main()
    {
        int i,j;
        R(n); R(S);
        for(i=1;i<=n;i++)
        {
            Time[i]=Time[i-1]+read(); Cost[i]=Cost[i-1]+read();
        }
        memset(dp,63,sizeof dp); dp[0]=0;
        for(i=1;i<=n;i++)
        {
            for(j=0;j<i;j++)
            {
                dp[i]=min(dp[i],dp[j]+Time[i]*(Cost[i]-Cost[j])+S*(Cost[n]-Cost[j]));
            }
        }
        Wl(dp[n]);
        return 0;
    }
    /*
    input
    5
    1
    1 3
    3 2
    4 3
    2 3
    1 4
    output
    153
    */
    n^2做法
  • 相关阅读:
    1112评论汇总
    二叉树前序中序后续(递归和非递归遍历)
    leetcode Best Time to Buy and Sell Stock III
    JNI(Java本地方法调用)
    中文分词工具介绍
    指针的引用
    Java变量方法初始化顺序
    Java数组与列表转换的java.lang.ClassCastException
    字符串或者数字数组全排列
    Hbase基本命令
  • 原文地址:https://www.cnblogs.com/gaojunonly1/p/10398523.html
Copyright © 2011-2022 走看看