列表

详情


NC51199. 任务安排1

描述

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。

输入描述

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

输出描述

一个数,最小的总费用。

示例1

输入:

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

输出:

153

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 9ms, 内存消耗: 480K, 提交时间: 2020-04-05 22:05:13

#include<bits/stdc++.h>
using namespace std;
long long dp[5010],sumt[5010],sumc[5010];
int main()
{
	int n,s;
	cin>>n>>s;
	for(int i=1;i<=n;i++)
	{
		int t,c;
		scanf("%d%d",&t,&c);
		sumt[i]=sumt[i-1]+t;
		sumc[i]=sumc[i-1]+c;
	}
	memset(dp,0x3f,sizeof(dp));
	dp[0]=0;
	for(int i=1;i<=n;i++)
		for(int j=0;j<i;j++)
			dp[i]=min(dp[i],dp[j]+sumt[i]*(sumc[i]-sumc[j])+s*(sumc[n]-sumc[j]));
	cout<<dp[n]<<endl;
	return 0;
}

C++(g++ 7.5.0) 解法, 执行用时: 8ms, 内存消耗: 520K, 提交时间: 2022-08-11 21:20:05

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll f[5555],m[5555];
ll u[5555],n,s;
int main()
{
	cin>>n>>s;
	for(int i=1; i<=n; i++)
	{
		int t,c;
		cin>>t>>c;
		m[i]=m[i-1]+t;
		u[i]=u[i-1]+c;
	}
	memset(f,0x3f,sizeof(f));
	f[0]=0;
	for(int i=1; i<=n; i++)
	for(int j=0; j<i; j++)
	f[i]=min(f[i],f[j]+m[i]*(u[i]-u[j])+s*(u[n]-u[j]));
	cout<<f[n]<<endl;
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 5ms, 内存消耗: 504K, 提交时间: 2020-10-19 19:39:06

#include<bits/stdc++.h>
using namespace std;
const int nn=5019;
int n,s,t[nn],c[nn],f[nn];
int main(){
	memset(f,0x3f,sizeof f);
	f[0]=0,scanf("%d%d",&n,&s);
	for(int i=1;i<=n;i++)
		scanf("%d%d",t+i,c+i),
		t[i]+=t[i-1],c[i]+=c[i-1];
	for(int i=1;i<=n;i++)
		for(int j=0;j<i;j++)
			f[i]=min(f[i],f[j]+t[i]*(c[i]-c[j])+s*(c[n]-c[j]));
	return printf("%d",f[n]),0;
}

上一题