缩短调度算法的运行时间

时间:2015-05-06 05:29:43

标签: c++ algorithm

假设一个开关需要a分钟开启一个灯,它开启b分钟。目的是在至少1分钟内打开灯并打开灯的顺序以打开,否则应打印-1

假设我输入如下:

2
1 5
5 10
  • 第一行是1< = n< = 10 ^ 4的有多少个开关。

  • 第二行是每个开关转动所需的时间 上。

  • 第三行是灯光持续多长时间。

所以一个开关:a = 1,b = 5,另一个开关:a = 5,b = 10

如果我们打开开关1然后打开2,它将看起来像这样:

let turn on time: 0
let on time: 1

011111
 0000011111

我们无法满足这个条件。另一方面,如果我们有2然后是1,那么它将是

0000011111
     011111

因此灯亮4分钟> 1这样很好,输出是

2 1

其他输入:

2
5 5
5 5

输出:-1(由于开启时间与其他时间相同)

3
1 4 1
5 3 4

输出:2 1 32 3 1

我的代码:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

class Switch {
public:
  int num;
  int turnon;
  int time;

  Switch(int n) { num = n; turnon = 0; time = 0; }
};

bool comparator(Switch a, Switch b) { return a.turnon > b.turnon; }

int main()
{
  int n=0;
  cin >> n;

  vector<Switch> v;
  for(int i=0; i<n; i++) {
    Switch s = Switch(i+1);
    v.push_back(s);
  }

  for(int i=0; i<n; i++) {
    int a = 0;
    cin >> a;
    v[i].turnon = a;
  }

  for(int i=0; i<n; i++) {
    int b = 0;
    cin >> b;
    v[i].time = b;
  }

  while(v.size() >= 1) {
    int maxtimeleft = -2147484637;
    int maxindex = 0;
    for(int i=0; i<v.size(); i++) {
      int time = v[i].time;
      for(int j=0; j<v.size(); j++) {
        if(j!=i)
          time -= v[j].turnon;
      }
      if(time > maxtimeleft) {
        maxtimeleft = time;
        maxindex = i;
      }     
    }
    if(maxtimeleft < 1) {
        cout << "-1";
        return 0;
    }
    cout << v[maxindex].num << endl;
    v.erase(v.begin()+maxindex);
  }

主要思路:我通过每个开关然后从其“准时”中减去所有其他开关的“开启时间”。我发现开关给了我剩下的最长时间,然后将其打印出来并将其移除,然后重复此操作直到只剩下一个开关。

此代码通过前三个测试,但未通过称为“时间限制错误”的测试。我想这是因为这个算法是一个O(n ^ 3)算法,因为它有两个for循环,寻找最好的删除开关,并重复它直到没有剩余的开关。关于如何改进这个的任何想法?这是一个家庭作业问题。

1 个答案:

答案 0 :(得分:1)

我能想到的最简短的解决方案是:

  1. 计算打开所有灯光所需的总时间(T)。
  2. 对于每个开关计算最早的时间点t_i,您可以将其打开,这样灯仍会在T + 1处燃烧。
  3. 根据该标准对开关进行排序。
  4. asymtotic复杂性由排序控制,所以你最终会得到O(n(log(n)))。

    根据数字的大小,您可以将空间换成时间,并通过为每分钟分配一个元素的向量并将每个开关直接放在位置,将其转​​换为一个带有线性的线性复杂度(可能具有高常数)的算法t_i在那个向量中。基本上,您正在创建一个非常稀疏的哈希表。

    最后,您可以动态调整粒度,但除非您有非常严格的时间和空间限制,否则我认为没有必要。