一:题目:宝宝 你要永远开心,下雪了,多穿点,
输入格式:
第一行输入作业个数n。
第二行输入各任务在机器一上的完成时间。
第三行输入各任务在机器二上的完成时间。
输出格式:
最短完成时间和
输入样例:
3
2 3 2
1 1 3
结尾无空行
输出样例:
18
二:思路
分析题意:
题目是批量处理作业调度,那么我们可以得知,这是让我们完成一个作业之后再去完成另一个作业
思路:
1.姑且先给我们的作业边上序号 a,b,c三个作业,那么我们可以得知关于这三个作业的
的安排有6种方式,那么我们的问题就简单了,这是一个全排列问题
2.回归本题,我们知道了是全排列问题,我们可以通过回溯法穷举所有的可行解,然后在
根据可行解求出最优值
3.回溯版的全排列,其实这和分治法那个一样,都是递归求全排列,
<1>:递归函数的参数
backtecking(int n,vector &v)
int n:表示我们选择的是n个作业 从1,2,3…这样的序列我们来求取
vector &v:这里表示我们递归的时候记录哪些元素我们已经访问过
<2>:返回的结果
vector<vector > ans; 存放每次的可行结
vector path; 记录每次的可行解
<3>:横向for循环 和 纵向的递归深度
for(int i = level; i <= n; i++)
我们单层的for循环是遍历我们所有的(1,2,3…)
纵向的递归:我们选择的是不断缩小的我们遍历的范围
<4>:递归终止条件
path.size() == n时,这时我们的一种可行结果(就是我们的一种安排作业的顺序 比如1,2,3或则2,1,3)
4:对上方的所有可行解求出最优解
5:图解
三:上码
/**分析题意:题目是批量处理作业调度,那么我们可以得知,这是让我们完成一个作业之后再去完成另一个作业思路:1.姑且先给我们的作业边上序号 a,b,c三个作业,那么我们可以得知关于这三个作业的的安排有6种方式,那么我们的问题就简单了,这是一个全排列问题2.回归本题,我们知道了是全排列问题,我们可以通过回溯法穷举所有的可行解,然后在根据可行解求出最优值3.回溯版的全排列,其实这和分治法那个一样,都是递归求全排列,<1>:递归函数的参数backtecking(int n,vector<bool> &v)int n:表示我们选择的是n个作业 从1,2,3....这样的序列我们来求取 vector<bool> &v:这里表示我们递归的时候记录哪些元素我们已经访问过 <2>:返回的结果vector<vector<int> > ans; 存放每次的可行结 vector<int> path; 记录每次的可行解<3>:横向for循环 和 纵向的递归深度 for(int i = level; i <= n; i++)我们单层的for循环是遍历我们所有的(1,2,3...)纵向的递归:我们选择的是不断缩小的我们遍历的范围<4>:递归终止条件path.size() == n时,这时我们的一种可行结果(就是我们的一种安排作业的顺序 比如1,2,3或则2,1,3) 4:对上方的所有可行解求出最优解
*/ #include<bits/stdc++.h>
using namespace std;vector<vector<int> > ans;
vector<int> path;void backtacking(int n,vector<bool> &v) {//递归终止的条件 if(path.size() == n){ans.push_back(path);return;}for(int i = 1; i <= n; i++) {if(v[i] == true) continue;v[i] = true;path.push_back(i);backtacking(n,v);//这里的level+1代表的是我们每次的遍历范围在变小 path.pop_back();//当我们得到一种可行解的时候,因为我们要回溯求取其他的解,所以清理最后装进容器的元素 v[i] = false;}
}int main(){int N;vector<int>v1(100),v2(100); vector<bool> v3(100,false);vector<int>v4;//记录最后每种排列的所求时间和 cin >> N;for (int i = 1; i <= N; i++) { cin >> v1[i];}for (int i = 1; i <= N; i++) {cin >> v2[i];} //cout << v1[1] << ' ' << v1[2] << ' ' << v1[3];backtacking(N,v3);//cout << endl;for (int i = 0; i < ans.size(); i++) {int sumTime1 = 0;int sumTime2 = 0; int sumTime3 = 0;//记录一种排列最后的完成总时间 for (int j = 0; j < N; j++){//cout << ans[i][j] << ' '; // 1 2 3 int index = ans[i][j];sumTime1 += v1[index];//这里计算在机器1上的完成时间 sumTime2 = sumTime1; //因为在机器二上的完成时间需要在机器1上完成后才可记录 sumTime2 += v2[index];//这里记录在机器2上的完成时间 sumTime3 += sumTime2;//记录所有作业的完成时间和 } v4.push_back(sumTime3);} sort(v4.begin(),v4.end());cout << v4[0];}
宝!我还得再唠叨一句 记得加油!!永远爱自己!!