林下的碼路(誠接遠端家教輔導:初高中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?- //演算法思想:區間覆蓋,先排序,總共就兩種情況。
- #include<iostream>
- #include<stdio.h>
- #include<fstream>
- #include<algorithm>
- usingnamespace std;
- #define Max(a,b) a>b?a:b
- typedefstruct
- {
- int s_time;
- int e_time;
- }D_farmers;
- D_farmers df[5001];
- int n;
- bool cmp(D_farmers a,D_farmers b)//起始時間的升序排序
- {
- return a.s_time<b.s_time||(a.s_time==b.s_time&&a.e_time<b.e_time);
- }
- int main()
- {
- ifstream fin("milk2.in");
- ofstream fout("milk2.out");
- int i,max1_t=0,max2_t=0,s_max,t_max;//s_max和t_max分別記錄最大起始時間和結束時間
- fin>>n;
- for(i=0;i<n;i++)
- fin>>df[i].s_time>>df[i].e_time;
- sort(df,df+n,cmp);//升序排序
- s_max=df[0].s_time;
- t_max=df[0].e_time;
- max1_t=df[0].e_time-df[0].s_time;
- //max2_t=df[0].s_time;
- for(i=1;i<n;i++)
- {
- if(t_max>=df[i].s_time&&df[i].e_time>=t_max)//前一個結束時間大於當前起始時間,更新新的截至時間,
- t_max=df[i].e_time;
- elseif(t_max<df[i].s_time)//前一個結束時間小於當前起始時間,進行判斷比較
- {
- //cout<<t_max<<endl;
- max1_t=Max(t_max-s_max,max1_t);
- //cout<<max1_t<<endl;
- max2_t=Max(df[i].s_time-t_max,max2_t);
- s_max=df[i].s_time;
- t_max=df[i].e_time;
- }
- }
- //cout<<max1_t<<" "<<max2_t<<endl;
- fout<<max1_t<<" "<<max2_t<<endl;
- return 0;
- }
以下內容複製於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來說,顯然選擇它的右端點是明智的。因為它比前面的點能覆蓋更大的範圍。
從而此情況下,貪心策略也是正確的。
- #include <stdio.h>
- #include <algorithm>
- usingnamespace std;
- struct Extent
- {
- int a,b;
- bool operator < (const Extent& S)const
- {
- return b < S.b || b == S.b && a > S.a;
- }
- }A[10002];
- int main()
- {
- int z,n,cnt,end;
- scanf("%d",&z);
- while(z--)
- {
-
相關推薦
林下的碼路(誠接遠端家教輔導:初高中NOI、大學ACM、CCPC、藍橋杯等演算法程式設計類程式設計競賽)
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
藍橋杯_演算法訓練_安慰奶牛(用Kruskal、Prim演算法分別實現)
問題描述 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下的SVN(Subversion)編譯&配置(附編譯好的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:我們遠端連線的之一端並不影響伺服器服務