日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

信息学奥赛一本通 1322:【例6.4】拦截导弹问题(Noip1999)

發布時間:2025/3/17 编程问答 73 豆豆
生活随笔 收集整理的這篇文章主要介紹了 信息学奥赛一本通 1322:【例6.4】拦截导弹问题(Noip1999) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【題目鏈接】

ybt 1322:【例6.4】攔截導彈問題(Noip1999)
原題有兩個問,本題為第2問

【題目考點】

1. 貪心

【解題思路】

hhh表示當前系統可以攔截的最高的高度。
貪心選擇:高度小于等于hhh的導彈中高度最高的導彈。
如果當前系統無法再攔截導彈,而且存在未被攔截的導彈,那么增加一個攔截系統,將hhh設為無窮大,繼續進行貪心選擇。

各導彈高度構成一個數字序列,每個攔截系統攔截的導彈的高度為原序列的不升子序列。該題可以抽象為:求一個數字序列的不升子序列的最少個數。
以下討論中使用抽象后的概念。

1. 貪心選擇性質的證明:

貪心選擇:選擇小于等于hhh的最大數字,而后將hhh設為該數字。如果不存在,開新的序列,將hhh設為無窮大。

該題的解為多個不升數字序列。

  • 證明:存在最優解包含第一次的貪心選擇,也就是說最大值ggg是某個數字序列的第一個數字。

    假設所有的最優解都中ggg都不是第一個數字,
    某最優解中,存在子序列a1,a2,...,g,...,ama_1, a_2, ...,g,..., a_ma1?,a2?,...,g,...,am?,由于該子序列為不升子序列,那么a1≤a2≤...≤ga_1 \le a_2 \le ... \le ga1?a2?...g,而ggg是所有數字中的最大值,因而有g≥a1g \ge a_1ga1?,所以a1=ga_1 = ga1?=g,該序列的第一個數字就是ggg,與假設相悖,原命題得證。

  • 證明:假設前k次都進行貪心選擇,存在最優解包含第k+1次的貪心選擇ggg
    1) 如果ggg是某子序列的第一個數

    假設所有的最優解都不包含第一個數是ggg的子序列,任選一個最優解,存在在第k次選擇后選擇到的數字構成的子序列a1,a2,...,g,...,ama_1, a_2, ...,g,..., a_ma1?,a2?,...,g,...,am?,由于該子序列為不升子序列,那么a1≥a2≥...≥ga_1 \ge a_2 \ge ... \ge ga1?a2?...g,而ggg是第k次選擇后選擇的數字中的最大值,因而有g≥a1g \ge a_1ga1?,所以a1=ga_1 = ga1?=g,該序列的第一個數字就是ggg,與假設相悖,原命題得證。

    2)如果ggg不是某子序列的第一個數
    也就是說,存在子序列ax,ax+1,...,aka_x, a_{x+1},... ,a_kax?,ax+1?,...,ak?aka_kak?是第k次的貪心選擇,前k次的貪心選擇已經固定。下一次貪心選擇是ggg,應該與aka_kak?在同一序列且在aka_kak?的后面。

    假設所有最優解中不存在aka_kak?在子序列中的下一個數字是ggg的情況。
    1.如果aka_kak?ggg仍然在同一子序列,那么有:ax,...,ak,ak+1,...,g,...,ama_x,... ,a_k, a_{k+1}, ...,g, ..., a_max?,...,ak?,ak+1?,...,g,...,am?
    已知g是第k次貪心選擇后選擇的數字中的最大數字,那么有g≥ak+1g \ge a_{k+1}gak+1?,因為這是不升序列,那么有ak+1≥ga_{k+1} \ge gak+1?g,所以ak+1=ga_{k+1} = gak+1?=gaka_kak?的下一個數字是ggg,與假設相悖。
    2.如果aka_kak?ggg不在同一子序列中,
    ggg不可能接在由前k次貪心選擇構成的老序列的后面。如果能接在老序列的后面,之前做貪心選擇時就會選到ggg
    因而ggg所在的序列一定是由第k次貪心選擇之后選擇到的數字組成的,可能為:ay,ay+1,...,ag?1,g,ag+1,...,agea_y, a_{y+1}, ..., a_{g-1}, g, a_{g+1}, ..., a_{ge}ay?,ay+1?,...,ag?1?,g,ag+1?,...,age?。這是不升序列,所以ay≥ga_y \ge gay?g
    由于ggg是第k次貪心選擇后剩余數字中的最大數字,所以ay≤ga_y \le gay?g,所以有ay=ga_y = gay?=g
    因此g一定是某個序列中的第一個數字,該序列為:g,ag?1,g,ag+1,...,ageg, a_{g-1}, g, a_{g+1}, ..., a_{ge}g,ag?1?,g,ag+1?,...,age?
    第k次貪心選擇aka_kak?存在的序列為ax,ax+1,...,ak,ak+1,...,ama_x, a_{x+1},... ,a_k, a_{k+1}, ..., a_max?,ax+1?,...,ak?,ak+1?,...,am?(也可能不存在ak+1,...,ama_{k+1}, ..., a_mak+1?,...,am?),
    由于g≤akg\le a_kgak?,序列ax,ax+1,...,ak,g,ag+1,...,agea_x, a_{x+1},... ,a_k, g, a_{g+1}, ..., a_{ge}ax?,ax+1?,...,ak?,g,ag+1?,...,age?一定也是不升序列。
    如果ak+1,...,ama_{k+1}, ..., a_mak+1?,...,am?不存在,則將ggg所在的序列接在aka_kak?的后面,構成序列ax,ax+1,...,ak,g,ag+1,...,agea_x, a_{x+1},... ,a_k, g, a_{g+1}, ..., a_{ge}ax?,ax+1?,...,ak?,g,ag+1?,...,age?,總序列數量減少,仍然是最優解。
    如果存在ak+1,...,ama_{k+1}, ..., a_mak+1?,...,am?,那么將序列g,ag+1,...,ageg, a_{g+1}, ..., a_{ge}g,ag+1?,...,age?ak+1,...,ama_{k+1}, ..., a_mak+1?,...,am?交換。得到序列ax,ax+1,...,ak,g,ag+1,...,agea_x, a_{x+1},... ,a_k, g, a_{g+1}, ..., a_{ge}ax?,ax+1?,...,ak?,g,ag+1?,...,age?ak+1,...,ama_{k+1}, ..., a_mak+1?,...,am?,總序列數量不變,仍是最優解。
    無論何總情況,總能構造出滿足aka_kak?在子序列中下一個數字是ggg的最優解。與假設相悖,假設不成立,原命題得證。

  • 2. 具體做法

    將導彈高度記錄在數組a中,設vis數組,表示第i個導彈是否已經被攔截。設h為無窮大。順序遍歷數組a,遇到小于等于h的數字,則攔截該導彈,記錄攔截導彈的個數。
    遍歷結束后,如果攔截到的導彈數量不足n,那么將h設為無窮大,再次遍歷該數組。重復上述過程,直到攔截的數量等于n。輸出遍歷的次數。

    【題解代碼】

    解法1:貪心

    #include<bits/stdc++.h> using namespace std; #define N 1005 #define INF 0x3f3f3f3f int main() {int a[N], n = 1, ct = 0, h, ans = 0;//ct:攔截的導彈數量 ans:遍歷了幾趟 bool vis[N] = {};while(cin >> a[n])n++;n--;while(ct < n){h = INF;for(int i = 1; i <= n; ++i){if(vis[i] == false && h >= a[i])//如果導彈i沒被攔截 且 可以被攔截 {h = a[i];vis[i] = true;ct++;}}ans++;}cout << ans;return 0; }

    總結

    以上是生活随笔為你收集整理的信息学奥赛一本通 1322:【例6.4】拦截导弹问题(Noip1999)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。