【Tyvj1098】任务安排

描述 Description

N 个任务排成一个序列在一台机器上等待完成(顺序不得改变),这 N 个任务被分成若干批,每批包含相邻的若干任务。从时刻 0 开始,这些任务被分批加工,第 i 个任务单独完成所需的时间是 Ti。在每批任务开始前,机器需要启动时间 S,而完成这批任务所需的时间是各个任务需要时间的总和(同一批任务将在同一时刻完成)。每个任务的费用是它的完成时刻乘以一个费用系数 Fi。请确定一个分组方案,使得总费用最小。

例如:S=1;T={1,3,4,2,1};F={3,2,3,3,4}。如果分组方案是 {1,2}、{3}、{4,5},则完成时间分别为 {5,5,10,14,14},费用 C={15,10,30,42,56},总费用就是 153。

输入格式 InputFormat

第一行是 N(1<=N<=5000)。
第二行是 S(0<=S<=50)。
下面 N 行每行有一对数,分别为 Ti 和 Fi,均为不大于 100 的正整数,表示第 i 个任务单独完成所需的时间是 Ti 及其费用系数 Fi。

输出格式 OutputFormat

一个数,最小的总费用。

样例输入 SampleInput

10
50
36 8
17 18
84 28
98 54
45 5
61 66
73 18
13 46
13 54
43 60

样例输出 SampleOutput

170820


Tyvj 1098


代码 Code

水。Tyvj 上的数据太弱了,数据范围大点的需要用到斜率优化。

#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define inf 0x7fffffff
int a[5005],b[5005]; 
int f[5005];
int i,j,t,n,m,l,r,k,s,z,y,x;
int main()
{
    scanf("%d%d",&n,&s);
    for (i=1;i<=n;i++)
    {
        scanf("%d%d",&x,&y);
        a[i]=a[i-1]+x;
        b[i]=b[i-1]+y;
        f[i]=inf;
    }
    for (i=1;i<=n;i++) for (j=1;j<=i;j++)
    {
        l=b[n]-b[j-1];
        r=b[i]-b[j-1];
        f[i]=min(f[i],f[j-1]+s*l+a[i]*r);
    }
    printf("%d\n",f[n]);
    return 0;
}