双核处理
描述
一种双核CPU的两个核能够同时的处理任务,现在有n个已知数据量的任务需要交给CPU处理,假设已知CPU的每个核1秒可以处理1kb,每个核同时只能处理一项任务。n个任务可以按照任意顺序放入CPU进行处理,现在需要设计一个方案让CPU处理完这批任务所需的时间最少,求这个最小的时间。
输入描述
输入包括两行:
第一行为整数n(1 ≤ n ≤ 50)
第二行为n个整数length[i](1024 ≤ length[i] ≤ 4194304),表示每个任务的长度为length[i]kb,每个数均为1024的倍数。
输出描述
输出一个整数,表示最少需要处理的时间
样例
输入
5
3072 3072 7168 3072 1024输出
9216
思路
最少时间肯定是两个核共同处理同时完成,但是因为任务不可分割,所以应该是两个核处理的时间相差越少越好,于是就相当于求一个核如何分配任务使得起处理时间与总时间的一半相差最少。于是就变成了01背包问题。
代码
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int miniTime(vector<int>length){
if (length.size() == 1) return length[0]*1024;
int sumTime=0;
for (int i = 0; i < length.size(); i++) sumTime += length[i];
int avgTime = sumTime / 2;
vector<int>column(avgTime+1, 0);
vector<vector<int>>m(length.size(), column);
for (int i = 0; i <= avgTime; i++){
if (length[0] > i) m[0][i] = 0;
else m[0][i] = length[0];
}
//0-1背包问题
for (int i = 1; i < length.size(); i++){//i为item
for (int j = 0; j <= avgTime; j++){//j为space
if (length[i] <= j){//可加入
m[i][j] = max(m[i - 1][j], m[i - 1][j - length[i]]+length[i]);
}
else{
m[i][j] = m[i - 1][j];
}
}
}
int miniT=m[length.size()-1][avgTime];
return (sumTime - miniT) * 1024;
}
int main(){
int n;
while (cin >> n){
vector<int> length;
for (int i = 0; i < n; i++){
int temp;
cin >> temp;
temp /= 1024;
length.push_back(temp);
}
cout << miniTime(length);
}
}
写在最后
对于动态规划中的经典问题背包问题
我之前一直是处于半懂状态,这次借此机会重温了一下背包问题,思路明显清晰了很多。其实动态规划也好,背包问题也好,最重要的就是要懂得将大问题分成小问题一步步来进行,加入大问题可以通过一小步来迭代求得,那么这就适合用动态规划思想处理。而背包问题难就难在很难找到这个小步,或者说是难以理解,其实理解了之后就和其他的动态规划问题相差无几。
对于调试
这次调试花了我大部分时间,每次都报“段错误”。多次修改才发现是自己对于一些边界输入没处理好,例如只有一个数据,或者极端情况下50个数据,而且数据都取最大,此时就要考虑是否超过变量范围和数组范围。