課程排程
題目內容:
有 n 個人,要完成 2 門課程。其中第 i 個人學習一門課程所需要的時間是 ti。
每個人同一時刻只能修一門課程,每門課程同一時刻只能被乙個人修,中間不能中斷。
問所有人都修完 2 門課程,至少需要多少時間。
輸入格式:
輸入的第一行包含乙個整數 n(1 <= n <= 1000000)。
接下來的一行包含 n 個整數 (1 <= ai <= 1000000000),表示每門課程的時間。
輸出格式:
輸出一行表示對應的答案。
輸入樣例:
3 2 2 2
3 4 1 2
4 1 3 2 1
輸出樣例:
6 8
7時間限制:2000ms記憶體限制:128000kb
思路是模擬兩個課程不斷挑選最合適的人來學,最合適的人 兩門課都沒學,並且學的時間是剩餘最長的。其次學完一門,學的時間是剩餘最長的。
#include
#include
using
namespace
std;
void max(int& class1, int class2, int &sum, int k, vector
> &p)
}}int main()
while (sum != 2 * n)
if (class2 < 0 || p[class2][1] == 0)
if (class1 >= 0 && p[class1][0]>0)
if (--p[class1][0] == 0)
sum++;
if (class2 >= 0 && p[class2][1]>0)
if (--p[class2][1] == 0)
sum++;
count++;
}cout
<< count << "\r\n";
}system("pause");
}
用例1過了,2超時
改
#include
#include
using
namespace
std;
void max(int& class1, int class2, int &sum, int k, vector
> &p)
}}int main()
while (sum != 2 * n)
if (class2 < 0 || p[class2][1] == 0)
if (class1 >= 0 && p[class1][0]>0)
if (--p[class1][0] == 0)
}if (class2 >= 0 && p[class2][1]>0)
if (--p[class2][1] == 0)
}count++;
}cout
<< count << "\r\n";
}system("pause");
}
用例1過了,2超時
再改
#include
#include
using
namespace
std;
void max(int& class1, int class2, int &sum, int k, vector
> &p)
}}int min(int a, int b)
int main()
while (sum != 2 * n)
if (class2 < 0 || p[class2][1] == 0)
int classmin;
if (class1 == -1)
else
if (class2 == -1)
else
if (class1 >= 0)
if (p[class1][0] == 0)
}if (class2 >= 0)
if (p[class2][1] == 0)
}count += classmin;
}cout
<< count << "\r\n";
}system("pause");
}
還是超時,越改越慢。然後就發現這道題其實很簡單,
思路,求出學一門課時間最長的人所需要的時間,即給的陣列的最大值max。求出陣列的和,結果就是2*max 與陣列的和兩個數中大的那個。
**如下:
#include
using namespace std;
int main()
else
}if (max
>
sum)
cout <<2*
max<<
"\r\n";
else
cout <<
max+
sum<<
"\r\n";
}system("pause");
}
證明方法:
為了簡單說明先排個序,實際上不用。
k1 k2 k3 …………kn 從大到小
先說一下,學完的最短時間就是陣列的和,而時間會比它長是因為第一節課與第二節課產生了衝突,即乙個人正在學第一節課,而第二節課沒學的也只剩他乙個了,所以要學完第二節課必須等他學完第一節課。
第一門課從k1開始學 k1 k2 k3….
第二門課從kn開始學 kn kn-1 kn-2 ……..
則兩門課會相遇,設在第m個人處相遇即在km處
若m!=1,則第二門課從km+1跳到k1處,由於k1>=km,所以當第乙個人的第二門課學完後第m個人的第一門課也一定學完。則第一門課與第二門課就不會有衝突了。(任意乙個人至少學了一門課)所用時間為 k1 + k2 + k3………+kn
若m==1(k1>k2+k3+….+kn),則第二節課要等第乙個人把第一節課學完才能讓他學習第二節課,第乙個人學完第一節課後再學第二節,因為(k1>k2+k3+….+kn),所以當他學完第二節課後,其他人也早將第一節課學完了,所用時間為 2*k1
上面程式中的 sum 是 k2+k3+….+kn,max 是 k1。
演算法設計與分析之貪心法
貪心法總是做出在當前看來最好的選擇,一旦做出了選擇,不管將來有什麼結果,這個選擇都不會改變。也就是說貪心法並不從整體最優考慮,它所作出的選擇只是在某種意義上的區域性最優選擇。當然,希望貪心法得到的最終結果也是整體最優的。雖然貪心法不能對所有問題都得到整體最優解,但對許多問題它能產生整體最優解。幾點說...
演算法設計與分析入門篇 分治作業 1
題目內容 給定 n 個數組成的陣列,求其逆序對的總數。逆序對定義為,存在 i,j 滿足 i j 且 a i a j 的二元組的數目。輸入格式 第一行包含乙個整數,表示陣列的項數。接下來的一行,包含 n 個數 leq 100000 依次表示 ai ai 109 輸出格式 輸出一行表示對應的答案。輸入樣...
演算法設計與分析入門篇 動態規劃 2
2括號子串行 a 10分 題目內容 一段括號序列被稱為平衡的,如果對於任意字首,左括號的數目都不小於右括號。給定一段括號序列,問有多少括號子串行是平衡的。內容相同但位置不同的算兩種。輸入格式 多組測試資料,每組測試資料報含一行乙個括號序列,括號序列的長度 100。輸出格式 輸出一行表示答案模 10 ...