防禦飛彈演算法,飛彈演算法

來源:互聯網
上載者:User

防禦飛彈演算法,飛彈演算法

演算法效率的時間空間效率完全沒有考慮(大鳥無噴),但是可能是最直觀的,最白癡的思路。沒有運用網上大部分的貪進法演算法思想,就是保證沒讀過演算法相關書籍的任何人都能讀懂。

 

題目出處:

http://www.programfan.com/acm/show.asp?qid=5

 

題目如下:

防禦飛彈

Problem

某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。

但是這種飛彈攔截系統有一個缺陷:雖然它的第一發炮彈能夠達到任意的高度,但是以後每一發炮彈都不能高於前一發的高度。

某天,雷達捕捉到敵國的飛彈來襲。由於該系統還在使用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。

Input

最多20個整數,分別表示飛彈依次飛來的高度(雷達給出高度資料是不大於30000的正整數)

Output

兩個整數M和N。表示:這套系統最多能攔截 M 枚飛彈,如果要攔截所有飛彈最少要配備 N 套這種飛彈系統。

Sample Input

300 250 275 252 200 138 245

Sample Output

5 2

 

看到問題,首先要從實際問題抽相出數學模型——問題翻譯:

1.求M本問題就是要求解某個隨機序列的最長降序序列2.求N就是每次從序列中選取最長降序序列,直到原序列中所有元素都被選出,得到的降序序列的個數就是所求N

例如:

300 250 275 252 200 138 245

每次選取最大降序序列,第一次選300,275,252,200,138第二次選250,245,現在所有的元素都被選完了,所以M為5,N為2。假設還有700,100兩個元素,100會被加入第一次選出的序列,700獨立成為一個序列,則M為6,N為3

 

思考:

對於目標序列S,分成兩段,其中S1為已經遍曆過的,S2為未遍曆過的。

運用某種資料結構,儲存S1中所有可能的降序序列段,然後每次把S2中的第一個元素加入S1,並修改S1所有的降序序列段,保證新產生的降序序列段為新的S1的降序序列段。

通過這個思路,可以想到用AOV網(拓撲排序)來儲存所有的降序序列段,每次從S2獲得新的元素添加進S1就相當於遍曆樹的所有節點,如果已儲存的節點的值大於等於新節點的值,則把該新節點的副本加入該節點的子序列。

所求的最長序列M就是AOV網的最大深度,所求的需要多少個系統N就是所有拓撲序列中,每次去除最長路徑上的所有節點,N次可以去除完所有節點。換句話說,每次拓撲排序,得到最多節點後把其全部摘除,產生的新圖再按照拓撲排序,得到最長的序列,再摘除,如此迴圈往複N次。

 

語言轉為代碼:

建立資料結構:分析到我們需要建立AOV網,運用遞迴可以很好的簡化代碼,因為產生的AOV網是一個有向非循環圖,所以每次遍曆所有節點,如果遍曆到的當前節點大於新加入的節點,則產生一條原節點到新節點的路徑。為了編碼方便,我們可以引入頭結點,頭結點的最大值就是其最大高度,保證有頭結點到剩餘所有節點的路徑,對於之後的編碼可以方便很多。

求出最長序列長度M:根據求樹的高度的代碼,我們可以很輕鬆的得出有向非循環圖的代碼,運用遞迴完成。

求N:這不是一個輕鬆的事,但是通過求M,我們可以得到每個節點的高度(節點的高度定義為:令最低終端節點為距離根節點最遠的節點,則節點高度為該節點距離最低終端節點的距離)。同時設定一個訪問位,用已經訪問來代表摘除該節點,又因為我們已經設定了一個頭結點,有到所有節點的訪問路勁,這就導致我們不會遺漏任何一個節點。


//程式碼分析:為了保證代碼的通用性(不僅僅局限於int類型),使用泛型程式設計。//    為了保證記憶體管理的方便性,使用智能指標。//          之所以選用set,而不用其他的容器,是因為set能保證插入的唯一性#include <memory>#include <algorithm>#include <iostream>#include <set>#define MAXALTITUDE 30000//飛彈最高高度#define GETARRAYSIZE(A) (sizeof(A)/sizeof(*A))//得到數組中元素的個數static int count = 0;//核心語句計數量template<class T>class DescendAov{private:bool isVisited;        //是否訪問過T value;//儲存當前節點的值std::set<std::shared_ptr<DescendAov> > minSet;//儲存比該節點值小的集合int maxAltitude;        //儲存每個節點的最大高度public:DescendAov(const T v) :value(v), isVisited(false), maxAltitude(0){};//通過值建AOV網DescendAov(T* sequence, int length) :DescendAov(MAXALTITUDE){//通過序列建AOV網for (int i = 0; i < length; ++i){//建立目標資料結構Insert(sequence[i]);} };int GetTheLengthOfTheLongestDescendSequence(int i = 0){//遍曆AOV網,得到AOV網的高度,就是所要求的最大降序序列長度int high = i;for (auto itr : minSet){high = std::max(itr->GetTheLengthOfTheLongestDescendSequence(i + 1), high);}maxAltitude = high;return high;}int GetLongestTopoSequenceNumber(){//得到最長拓撲序列的數量int num = 0;GetTheLengthOfTheLongestDescendSequence();//保證已經得出每個節點的高度for (unsigned int i = 0; i < minSet.size(); ++i){if (FindTheHighestNode())num++;elsebreak;}return num;}private:void Insert(const std::shared_ptr<DescendAov> d){//插入後繼++count;if (d->value <= value && this != d.get()){//如果節點值value大於等於新加入的節點值d->value,則添加進比他小的集合,this!=d.get()是為了防止自身重複插入自身。for (auto itr : minSet){itr->Insert(d);}minSet.insert(d);}}void Insert(const T &t){auto ptr = std::shared_ptr<DescendAov<T>>(new DescendAov<T>(t));Insert(ptr);}bool FindTheHighestNode(){//找到與該節點相串連的最高且未被訪問過的節點std::shared_ptr<DescendAov<T>> Highest = NULL;for (auto itr : minSet){if (!itr->isVisited){//未被訪問過if (!Highest || Highest->maxAltitude <= itr->maxAltitude)//如果當前節點為空白或者當前節點更高Highest = itr;}}if (!Highest)//找不到合適的節點有兩種情況:1.所有節點被放過問;2.當前節點為最後一個節點return false;Highest->isVisited = true;Highest->FindTheHighestNode();return true;}};int _tmain(int argc, _TCHAR* argv[]){int missile[] = { 300, 250, 275, 252, 200, 138, 245,700,100};DescendAov<int> root(missile, GETARRAYSIZE(missile));std::cout <<"最多攔截的飛彈數:" << root.GetTheLengthOfTheLongestDescendSequence() << std::endl;std::cout << "需要多少套系統:" << root.GetLongestTopoSequenceNumber() << std::endl;std::cout << "核心代碼迴圈次數:" << count << std::endl;return 0;}



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.