问题描述:
用2台机器A和B处理n个作业。设第i个作业交给机器A处理时需要时间ai,若由机器B来处理,则需要时间bi。由于各作业的特点和机器的性能关系,很可能对于某些i,有ai≥bi,而对某些j,有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)。
数据输入:
由文件input.txt提供输入数据。文件的第一行是1个正整数n,表示要处理n个作业。左接下来的2行中,每行有n个正整数,分别表示机器A和机器B处理第i个作业需要的处理时间。
结果输出:
将计算的最短处理时间输出到文件output.txt。
input.txt
6
2 5 7 10 5 2
3 8 4 11 3 4
output.txt
15
#include <iostream>
#include <vector>
using namespace std;
#define MAXN 100010
/*
6
A:2 5 7 10 5 2
B:3 8 4 11 3 4
最极端的情况下,所有任务都交给一台机器完成,则其完成的系列事件的事件最多为sum(a_i)或sum(b_i)。
设dp数组bool dp[i][j][k],表示前k个作业能否在处理机A总用时不超过i(i<=sum(a_i)),且在处理机B总用时不超过j(j<=sum(b_i))的情况下完成。 递推公式推导 1、假设第k个作业选择处理机A,则dp[i][j][k] = dp[i-a_k][j][k-1](i>=a_k)
2、假设第k个作业选择处理机B,则dp[i][j][k] = dp[i][j-b_k][k-1](j>=b_k)
3、综合考虑两种情况,则dp[i][j][k] = dp[i-a_k][j][k-1] || dp[i][j-b_k][k-1];
1.若dp[i-a_k][j][k-1]为true,则说明前k-1个作业可以在此之前完成,则其在此刻选择处理机A,也可以在dp[i][j][k]时刻完成;
2.若dp[i][j-b_k][k-1]为true,则说明前k-1个作业可以在此之前完成,则其在此刻选择处理机B,也可以在dp[i][j][k]时刻完成;
3.true||true = true, true||false = true, false||true = true, false||false = false。
4、遍历取出n对应的true,计算花费的最少时间。(每个true的x轴y轴较大的那个值的最小值)
*/
int n;//作业数
int a[MAXN], b[MAXN];//作业花费时间
vector<vector<vector > > dp;
int sum_a = 0, sum_b = 0;
void init(){
cin>>n;
for(int i=0;i<n;i++){ cin>>a[i];
sum_a += a[i];
}
for(int i=0;i<n;i++){ cin>>b[i];
sum_b += b[i];
}
dp = vector<vector<vector>>(sum_a + 1, vector<vector>(sum_b + 1, vector(n + 1, false)));//dp从作业数为0开始
for(int i=0;i<=sum_a;i++){
for(int j=0;j<=sum_b;j++){
dp[i][j][0] = true;//若没有作业,则必可以完成
}
}
}
void solve(){
for(int k=1;k<=n;k++){//遍历n个作业
for(int i=0;i<=sum_a;i++){//遍历处理机A的总用时
for(int j=0;j<=sum_b;j++){//遍历处理机B的总用时 if(i >= a[k-1]){//选择处理机A
dp[i][j][k] = dp[i-a[k-1]][j][k-1];
}
if(j >= b[k-1]){//选择处理机B
dp[i][j][k] = dp[i][j-b[k-1]][k-1] || dp[i][j][k];
}
}
}
}
}
void getOptimalTime(){
int optimal_time = max(sum_a, sum_b);
for(int i=0;i<=sum_a;i++){
for(int j=0;j<=sum_b;j++){
if(dp[i][j][n]){
int tempOptimalTime = max(i, j);//选择处理机A或B的较大值
if(tempOptimalTime < optimal_time){//更新最优时间
optimal_time = tempOptimalTime;
}
}
}
}
cout<<optimal_time<<endl;
}
int main(){
init();
solve();
getOptimalTime();
return 0;
}
/*
6
2 5 7 10 5 2
3 8 4 11 3 4
*/

最新评论