问题描述:
用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 */
最新评论