P2365 任务安排
题目描述
n 个任务排成一个序列在一台机器上等待完成(顺序不得改变),这 n 个任务被分成若干批,每批包含相邻的若干任务。
从零时刻开始,这些任务被分批加工,第 i 个任务单独完成所需的时间为 ti。在每批任务开始前,机器需要启动时间 s,而完成这批任务所需的时间是各个任务需要时间的总和(同一批任务将在同一时刻完成)。
每个任务的费用是它的完成时刻乘以一个费用系数 f i。请确定一个分组方案,使得总费用最小。
输入格式
第一行一个正整数 n。
第二行是一个整数 s。
下面 n 行每行有一对数,分别为 ti 和 fi,表示第 i 个任务单独完成所需的时间是 ti 及其费用系数 fi。
输出格式
一个数,最小的总费用。
输入输出样例
输入
5 1 1 3 3 2 4 3 2 3 1 4
输出
153
分析
dp[i]表示完成前i个任务所需的最小费用,用time[i]表示前i项任务所需的时间,用money[i]表示前i项任务一共的费用系数。
如果在完成第j项任务是启动一次机器,后面的所有任务完成的时刻都要加上s,所以每启动一次机器的费用为s * (money[n] - money[j- 1 ]);
如果把第j项任务和第i项任务和在一起做,则它们的完成时刻为time[i],所以费用为time[i] * (money[i] - money[j - 1])。
别把数组名设置成time会冲突
程序
#include <bits/stdc++.h> using namespace std; const int MAXN = 0x3f3f3f3f; int dp[100001]; int n , Time[100001] , money[100001] , s; int main () { ios::sync_with_stdio(false); cin >> n >> s; for (int i = 1; i <= n; i++) { cin >> Time[i] >> money[i]; Time[i] += Time[i - 1]; money[i] += money[i - 1]; dp[i]=MAXN; } for (int i = 1; i <= n; i++) for (int j = 1; j <= i; j++) dp[i] = min(dp[i] , dp[j - 1] + s * (money[n] - money[j - 1]) + Time[i] * (money[i] - money[j - 1])); cout << dp[n]; return 0; }