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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

信息学奥赛一本通 1324:【例6.6】整数区间

發布時間:2025/3/17 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 信息学奥赛一本通 1324:【例6.6】整数区间 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【題目鏈接】

ybt 1324:【例6.6】整數區間

【題目考點】

1. 貪心

2. 貪心選擇性質的證明

要想證明貪心選擇可以得到最優解,只需要證明最優解包含每一次的貪心選擇。
使用數學歸納法:

  • 證明最優解包含第一次的貪心選擇
  • 假設存在最優解包含前k次的貪心選擇,證明該最優解包含第k+1次的貪心選擇
  • 【解題思路】

    每次選擇右端最小的區間的右端數字,并刪掉所有包含該數字的區間。
    用數學語言說,現有區間:e1=[l1,r1],e2=[l2,r2],...,en=[ln,rn]e_1=[l_1,r_1], e_2=[l_2,r_2],...,e_n=[l_n,r_n]e1?=[l1?,r1?],e2?=[l2?,r2?],...,en?=[ln?,rn?]
    選擇右端點r最小的區間em=[lm,rm]e_m=[l_m,r_m]em?=[lm?,rm?],刪掉所有滿足rm∈exr_m\in e_xrm?ex?的區間exe_xex?

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

    貪心選擇:每次選擇右端最小的區間的右端點數字

  • 證明:存在最優解包含右端最小的區間的右端點數字
  • 記右端最小的區間為em=[lm,rm]e_m = [l_m,r_m]em?=[lm?,rm?],證明存在最優解包含rmr_mrm?
    使用反證法:假設所有最優解都不包含rmr_mrm?
    對于某一最優解,根據題意:“對于每一個區間,都至少有一個整數屬于該集合”,所以一定要在區間eme_mem?中選擇一個數字。假設該最優解中選擇了區間eme_mem?中的數字xxxx≠rmx \neq r_mx?=rm?,包含x的區間有p個,組成的集合為:Ex={ex1,ex2,...,exp}E_x = \{e_{x1},e_{x2},...,e_{xp}\}Ex?={ex1?,ex2?,...,exp?},選擇x后,這些區間都被刪掉,不再被考慮。
    現在考慮在該最優解中用rmr_mrm?替換xxx,包含rmr_mrm?的區間有q個,組成集合為:Er={er1,er2,...,erq}E_r=\{e_{r1},e_{r2},...,e_{rq}\}Er?={er1?,er2?,...,erq?},由于eme_mem?是右端最小的區間,所以ExE_xEx?中的所有區間的右端都大于等于rmr_mrm?,也就是說rmr_mrm?ExE_xEx?的每個區間中,亦即Ex?ErE_x\subseteq E_rEx??Er?。選擇rmr_mrm?后,ErE_rEr?中的所有區間都被刪除,包括了ExE_xEx?中的所有區間。該最優解中其他數字不變,仍然可以形成一組最優解。而這組最優解包含了rmr_mrm?,與假設相悖。因而原命題得證。

  • 證明:在k次貪心選擇后,存在最優解包含這一次的貪心選擇:剩余的區間中右端最小的區間的右端點數字
  • 證明方法與證明第1點相似,不再贅述。

    2. 具體做法

    將所有區間排序,排序規則為:右端小的排在前面;如果右端相同,那么左端小的排在前面。
    按順序遍歷各個區間,選擇當前區間的右端點并記錄,選擇的數字個數加1。
    繼續遍歷,如果當前區間的左端點小于等于之前記錄的右端點,那么略過這個區間。
    如果當前區間左端點大于之前記錄的右端點,那么選擇當前區間的右端點并記錄,選擇的數字個數加1。
    重復上述過程,直至遍歷完所有區間。

    【題解代碼】

    解法1:貪心

    #include<bits/stdc++.h> using namespace std; struct Sec {int l, r;//l:區間左端點 r:區間右端點 }; bool cmp(const Sec &a, const Sec &b) {//右端點更小的排在前面,右端點相同則左端點更小的在前面 if(a.r == b.r)return a.l < b.l;elsereturn a.r < b.r; } int main() {Sec s[10005];int n, ct = 0, lastR = -1;//lastR:上一個選擇的右端點 ct:選擇的數字個數cin >> n;for(int i = 1; i <= n; ++i)cin >> s[i].l >> s[i].r;sort(s+1, s+1+n, cmp);for(int i = 1; i <= n; ++i){if(s[i].l > lastR){ct++;lastR = s[i].r; }}cout << ct;return 0; }

    總結

    以上是生活随笔為你收集整理的信息学奥赛一本通 1324:【例6.6】整数区间的全部內容,希望文章能夠幫你解決所遇到的問題。

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