1. 程式人生 > >林下的碼路(誠接遠端家教輔導:初高中NOI、大學ACM、CCPC、藍橋杯等演算法程式設計類程式設計競賽)

林下的碼路(誠接遠端家教輔導:初高中NOI、大學ACM、CCPC、藍橋杯等演算法程式設計類程式設計競賽)

1)區間完全覆蓋問題

問題描述:給定一個長度為m的區間,再給出n條線段的起點和終點(注意這裡是閉區間),求最少使用多少條線段可以將整個區間完全覆蓋

樣例:

區間長度8,可選的覆蓋線段[2,6],[1,4],[3,6],[3,7],[6,8],[2,4],[3,5]

解題過程:

1將每一個區間按照左端點遞增順序排列,拍完序後為[1,4][2,4][2,6][3,5][3,6][3,7][6,8]

2設定一個變量表示已經覆蓋到的區域。再剩下的線段中找出所有左端點小於等於當前已經覆蓋到的區域的右端點的線段中,右端點最大的線段在加入,直到已經覆蓋全部的區域

3過程:

假設第一步加入[1,4],那麼下一步能夠選擇的有[2,6][3,5][3,6][3,7],由於7最大,所以下一步選擇[3,7],最後一步只能選擇[6,8],這個時候剛好達到了8退出,所選區間為3

4貪心證明:

需要最少的線段進行覆蓋,那麼選取的線段必然要儘量長,而已經覆蓋到的區域之前的地方已經無所謂了,(可以理解成所有的可以覆蓋的左端點都是已經覆蓋到的地方),那麼真正能夠使得線段更成的是右端點,左端點沒有太大的意義,所以選擇右端點來覆蓋

2)最大不相交覆蓋

問題描述:給定一個長度為m的區間,再給出n條線段的起點和終點(開區間和閉區間處理的方法是不同,這裡以開區間為例),問題是從中選取儘量多的線段,使得每個線段都是獨立的,就是不和其它有任何線段有相交的地方


樣例:

區間長度8,可選的覆蓋線段[2,6],[1,4],[3,6],[3,7],[6,8],[2,4],[3,5]

解題過程:

對線段的右端點進行升序排序,每加入一個線段,然後選擇後面若干個(也有可能是一個)右端點相同的線段,選擇左端點最大的那一條,如果加入以後不會跟之前的線段產生公共部分,那麼就加入,否則就繼續判斷後面的線段

1排序:將每一個區間按右端點進行遞增順序排列,拍完序後為[1,4][2,4][2,6][3,5][3,6][3,7][6,8]

2第一步選取[2,4],發現後面只能加入[6,8],以區間的個數為2


貪心證明

:因為需要儘量多的獨立的線段,所以每個線段都儘可能的小,對於同一右端點,左端點越大,線段長度越小。那麼為什麼要對右端點進行排序呢?如果左端點進行排序,那麼右端點是多少並不知道,那麼每一條線段都不能對之前所有的線段進行一個總結,那麼這就明顯不滿足貪心的最有字結構了。

3)區間選點問題

問題描述:給定一個長度為m的區間,再給出n條線段和這n條線段需要滿足的要求(要求是這n條線段上至少有的被選擇的點的個數),問題是整個區間內最少選擇幾個點,使其滿足每一條線段的要求.

樣例:略

解題過程:將每個線段按照終點座標進行遞增排序,相同終點的前點座標大的在前面,一個個將其滿足

貪心證明:要想使得剩下的線段上選擇的點最少,那麼就應該儘量使得已經選擇了的點儘量能在後面的線段中發揮作用,而我們是從左往右選擇線段的,那麼要使得選取的點能滿足後面線段的要求,那麼必須是從線段的有端點開始選點,那麼問題(2)一樣涉及到一個問題,如果是按照線段的左端點對線段進行排序的話,不知道右端點的話,每一條線段都不能對之前已經操作過的所有線段進行一個總結,那麼這就同樣不滿足貪心演算法的最優子結構性質了。

可以解決的實際問題:數軸上面有n個閉區間[a,b],取儘量少的點,使得每個區間內都至少有一個點(不同區間內含的點可以是同一個)

例項(類似第一種區間覆蓋,只不過求最大值)

三個農民每天清晨5點起床,然後去牛棚給3頭牛擠奶。第一個農民在300時刻(從5點開始計時,秒為單位)給他的牛擠奶,一直到1000時刻。第二個農民在700時刻開始,在 1200時刻結束。第三個農民在1500時刻開始2100時刻結束。期間最長的至少有一個農民在擠奶的連續時間為900秒(從300時刻到1200時刻),而最長的無人擠奶的連續時間(從擠奶開始一直到擠奶結束)為300時刻(從1200時刻到1500時刻)。  你的任務是編一個程式,讀入一個有N個農民(1 <= N <= 5000)擠N頭牛的工作時間列表,計算以下兩點(均以秒為單位):  最長至少有一人在擠奶的時間段。  最長的無人擠奶的時間段。(從有人擠奶開始算起)

Input

Line 1:  一個整數N。  Lines 2..N+1:  每行兩個小於1000000的非負整數,表示一個農民的開始時刻與結束時刻。 

Output

一行,兩個整數,即題目所要求的兩個答案。

Sample Input

3
300 1000
700 1200
1500 2100

Sample Output

900 300

參考程式碼:

[cpp] view plaincopyprint?
  1. //演算法思想:區間覆蓋,先排序,總共就兩種情況。
  2. #include<iostream>
  3. #include<stdio.h>
  4. #include<fstream>
  5. #include<algorithm>
  6. usingnamespace std;  
  7. #define Max(a,b) a>b?a:b
  8. typedefstruct
  9. {  
  10.   int s_time;  
  11.   int e_time;  
  12. }D_farmers;  
  13. D_farmers df[5001];  
  14. int n;  
  15. bool cmp(D_farmers a,D_farmers b)//起始時間的升序排序
  16. {  
  17.     return a.s_time<b.s_time||(a.s_time==b.s_time&&a.e_time<b.e_time);  
  18. }  
  19. int main()  
  20. {  
  21.     ifstream fin("milk2.in");  
  22.     ofstream fout("milk2.out");  
  23.     int i,max1_t=0,max2_t=0,s_max,t_max;//s_max和t_max分別記錄最大起始時間和結束時間
  24.     fin>>n;  
  25.     for(i=0;i<n;i++)  
  26.         fin>>df[i].s_time>>df[i].e_time;  
  27.     sort(df,df+n,cmp);//升序排序
  28.     s_max=df[0].s_time;  
  29.     t_max=df[0].e_time;  
  30.     max1_t=df[0].e_time-df[0].s_time;  
  31.     //max2_t=df[0].s_time;
  32.     for(i=1;i<n;i++)  
  33.     {  
  34.      if(t_max>=df[i].s_time&&df[i].e_time>=t_max)//前一個結束時間大於當前起始時間,更新新的截至時間,
  35.         t_max=df[i].e_time;  
  36.      elseif(t_max<df[i].s_time)//前一個結束時間小於當前起始時間,進行判斷比較
  37.       {  
  38.          //cout<<t_max<<endl;
  39.          max1_t=Max(t_max-s_max,max1_t);  
  40.          //cout<<max1_t<<endl;
  41.          max2_t=Max(df[i].s_time-t_max,max2_t);  
  42.          s_max=df[i].s_time;  
  43.          t_max=df[i].e_time;  
  44.       }  
  45.     }  
  46.     //cout<<max1_t<<" "<<max2_t<<endl;
  47.     fout<<max1_t<<" "<<max2_t<<endl;  
  48.     return 0;  
  49. }  

以下內容複製於http://blog.csdn.net/dgq8211/article/details/7534776

先來看看什麼是區間選點問題

數軸上有n個閉區間[ai,bi]。取儘量少的點,使得每個區間內都至少有一個點(不同區間內含的點可以是同一個)。

貪心策略:

按照b1<=b2<=b3…(b相同時按a從大到小)的方式排序排序,從前向後遍歷,當遇到沒有加入集合的區間時,選取這個區間的右端點b。

證明:

為了方便起見,如果區間i內已經有一個點被取到,我們稱區間i被滿足。

1、首先考慮區間包含的情況,當小區間被滿足時大區間一定被滿足。所以我們應當優先選取小區間中的點,從而使大區間不用考慮。

      按照上面的方式排序後,如果出現區間包含的情況,小區間一定在大區間前面。所以此情況下我們會優先選擇小區間。

      則此情況下,貪心策略是正確的。

2、排除情況1後,一定有a1<=a2<=a3……。


      對於區間1來說,顯然選擇它的右端點是明智的。因為它比前面的點能覆蓋更大的範圍。

      從而此情況下,貪心策略也是正確的。


  1. #include <stdio.h>
  2. #include <algorithm>
  3. usingnamespace std;  
  4. struct Extent  
  5. {  
  6.     int a,b;  
  7.     bool operator < (const Extent& S)const
  8.     {  
  9.         return b < S.b || b == S.b && a > S.a;  
  10.     }  
  11. }A[10002];  
  12. int main()  
  13. {  
  14.     int z,n,cnt,end;  
  15.     scanf("%d",&z);  
  16.     while(z--)  
  17.     {  
  18. 相關推薦

    遠端家教輔導初高中NOI大學ACMCCPC藍橋演算法程式設計程式設計競賽

    1)區間完全覆蓋問題 問題描述:給定一個長度為m的區間,再給出n條線段的起點和終點(注意這裡是閉區間),求最少使用多少條線段可以將整個區間完全覆蓋 樣例: 區間長度8,可選的覆蓋線段[2,6],[1,4],[3,6],[3,7],[6,8],[2

    快速開發趣事我與小白妹紙的漫漫擼1

    快速開發 快速開發平臺 快速開發框架 最近,活兒又來了,真是屋漏偏逢連陰雨,經過半年的洗禮能用得上的開發就我一個人了,怎麽辦呢,唉呀媽呀,腦殼疼腦殼疼...

    java學習筆記--物件程式設計-與方法

    面向過程-程式設計正規化-c-行為 面向物件-能進行現實生活的抽象 面向介面程式設計 面向切面程式設計 函數語言程式設計正規化 -Scala,Koltin //lamdba表示式 ()-> { } 面向物件三大特徵: a.封裝        將客觀事物

    藍橋_演算法訓練_Torry的困惑基本型

    這個題目就是求質數的乘積,在加一個模,思路比較簡單,直接上程式碼: 1 #include<iostream> 2 using namespace std; 3 bool isPrim

    藍橋_演算法訓練_安慰奶牛用KruskalPrim演算法分別實現

    問題描述 Farmer John變得非常懶,他不想再繼續維護供奶牛之間供通行的道路。 道路被用來連線N個牧場,牧場被連續地編號為1到N。每一個牧場都是一個奶牛的家。 FJ計劃除去P條道路中儘可能多的道路,但是還要保持牧場之間 的連通性。 你首先要決定那些

    樹莓派進階之 (023) - Windows用串行連控制樹莓派

    最新版 一個 問題 conn get 鏡像 under tty 打開 轉載:http://shumeipai.nxez.com/2014/05/04/under-windows-serial-connection-control-raspberry-pi.html 在沒有鍵

    android源編譯——從此走上Liunx的不歸

    彈出 oid log 按鈕 鍵盤 點擊 使用 andro android Ubuntu安裝:   1.啟動虛擬機進入到如下界面:         2.下拉找到“中文(簡體)”選項,然後選擇“安裝Ubuntu”:         3.點擊繼續:         4.選擇清除整

    android源編譯——從此走上Liunx的不歸

    article down 安裝git https ani 同步 版本 bsp rep 下載android源碼: 1.安裝git和curl: sudo apt-get install git-core sudo apt-get install git-core curl 2

    二次元農的成長之json到底有什麽用途

    頁面 asc 語法 處理 交互 分隔 規則 stl 成長之路 寫的有問題請指出 一、什麽是json 1json指的是javaScript的表示方法 2JSON是輕量級的文本數據交換格式 3 Json是獨立語言 4 json具有自我描述性 更易理解 二、語法規則 1對

    WD My Cloud Ex2 Ultra的SVNSubversion編譯&配置附編譯好的SVN的鏈

    ron header sql mit arm-linux _file__ 4.2 ... mut 前言 前些陣子買了個WD的My Cloud EX2 Ultra,主要就是為了存放重要資料啥的。買回來發現配套的軟件中竟然沒有svn,於是便有了這篇折騰隨筆了。 軟硬件環境 1

    二次元農的成長之I/O復習1

    應用 exceptio row har 字節數 對象 i/o rgs clas 一、什麽是流 它代表了有能力產出數據的對象或者有能力接受數據的對象 java類庫的I/O由輸入輸出兩部分組成 二、 inputStream InputStreamReader Read的關系 1

    用js載文件需要後端鏈

    span zip blank htm toolbar 代碼 window 新窗口 json 用js下載文件 PS:本文說的,並非如何用js創建流、創建文件、實現下載功能。 而是說的:你已知一個下載文件的後端接口,前端如何請求該接口,實現點擊按鈕、下載文件到本地。

    git 在windows的應用 - 遠程倉庫代管理

    軟件研發 研發管理 克隆遠程git 目錄https://github.com/pcdogyu/git4windows.git克隆下來了生成1.txtscan stage signoff commit2次提交記錄推送到遠程地址完成了還沒來得及去網頁呢,就收到系統提示郵件網頁查看1.txt已經提交上去了對

    git 在windows的應用 - 本地倉庫代管理

    軟件研發 研發管理 訪問https://gitforwindows.org/? 下載一個安裝包,一路next下去git config --global user.name "Pcdog" git config --global user.email "[email protected]"cd d:

    Hive學習之 DbVisualizer配置連hive

    ado lan inf files AD sha comm HR 下載地址 一、安裝DbVisualizer 下載地址http://www.dbvis.com/ 也可以從網上下載破解版程序,此處使用的版本是DbVisualizer 9.1.1 具體的安裝步驟可以百度,

    分享一些免費的平臺國外號碼

    org lan tro padding 德國 targe align reg 服務 名稱 網址 號碼所在國家 備註 SMS Receive Free https://smsreceivefree.com/ 加拿大、美國 SMS on

    Spark學習之 十五SparkCore的源解讀啟動腳本

    -o 啟動服務 binary dirname ppi std 參數 exp 情況 一、啟動腳本分析 獨立部署模式下,主要由master和slaves組成,master可以利用zk實現高可用性,其driver,work,app等信息可以持久化到zk上;slaves由一臺至多

    idea關聯spark源環境

    src orm format 2.4.0 truct hadoop XP 代碼更新 sem 0.環境: java 1.8 scala 2.11.8 maven 3.5.0 idea 2017 spark 2.2.0 1完成以下配置 java環境變量 scala環境變量 m

    RabbitMQ探索之RabbitMQ在Linux的安裝

    img out c-c++ line info evel 驅動 unixodbc local 一:系統準備 這裏我是在VMare上安裝了3臺CenOS7 64位系統,準備後期做分布式消息隊列用。 二:安裝步驟: 1.必備軟件毫無疑問是Elang以

    如何讓程式在linux伺服器一直執行關閉遠端連線後仍然繼續執行

    一、為什麼要使程式在後臺執行 最近剛剛入手在做一個遠端通訊的專案,利用套接字實現長連線通訊。那麼問題來了,我的服務端程式怎麼才能一直在伺服器上執行以達到隨時監測使用者請求的目的呢?查了幾篇部落格,解決了,記一下筆記。程式在後臺跑有以下2個好處: 1:我們遠端連線的之一端並不影響伺服器服務