本來以為這道題是考不相交區間, 結果還專門複習了一遍前面寫的, 然後發現這道題的區間是不是
固定的, 是在乙個範圍內「滑動的」, 只要右端點不超過截止時間就ok。
然後我就先考慮有包含關係的時候怎麼選, 然後發現當兩個區間只能放乙個的時候時間更短而截
至時間更長的時候,顯然更優。然後我就試著每個區間放的時候後後面的比較, 如果兩個區間只能放乙個, 而且
下個區間更優, 那麼當前的就不選。然後排除掉這些區間之後, 能選的就選。
交上去wa。然後我發現中間的區間排除了,但是前面和後面的區間可能會矛盾, 也要排除
我就想不到什麼方法來實現了。
後來參考了
發現我其實已經想了80%了, 但是最後20%怎麼實現沒有想到。這裡用到優先佇列來實現,
優先佇列中儲存了之前已經放過的所有區間, 然後能放就放, 不能放就往前和已經放了
的區間比較, 更優的話就放當前的區間, 取消之前的區間。
一直怎麼做就可以了。這麼做為什麼可以呢, 因為這樣就可以考慮到所有區間之間的「包含」關係
讓所有區間裡面最不優的都捨去了, 所以最後答案就是最優的。
然後我就繼續想,為什麼紫書前面講區間的時候都是相鄰的比較來捨去, 而這個要考慮前面所有
放過的區間。
然後我發現, 紫書上選區間的時候是前乙個比後乙個更優的。
然而這道題,放的時候相鄰的兩個區間不一定前乙個優於後乙個, 因為就算後乙個更差, 只要
不超過截止時間, 就可以放。
那麼這就導致了, 這道題排在後面的區間顯然不一定優於前面的區間(優指時間更短且截止時間更後),
所以不具有連續性, 也就是說要考慮當前區間和前面所有區間裡面「最差」的那乙個, 也就是需要時間最長
的乙個來取最優, 所以這才證明了貪心的正確性。
我覺得自己講得非常抽象, 看不懂也可以簡單的理解為能放就放, 不能放就拿乙個最差的來換, 這樣結果
肯定是最優的。
#include#include#include#define rep(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;
const int maxn = 812345;
struct node
}a[maxn];
bool cmp(node a, node b)
int main()
} printf("%d\n", q.size());
if(t) puts(""); }
return 0;
}
紫書 習題 9 8 uva1632
題意 有n個寶藏,每個都在乙個位置p i 在規定的時間t i 就會消失。阿里巴巴要在寶藏消失前收集齊所有寶藏,問 有方法嗎?有的話最少多少秒?思路 開始想的是用狀態轉移方程來乙個個判斷,不好寫。看了題解知道在一段區間 l,r 要使時間最短必須從端點出來,然後果斷寫了乙個記憶化搜尋,tle了。再看題解...
紫書 習題 9 8 uva 10163
解題感想 好久沒刷題了,自己連揹包dp都差不多忘了。題目看著很複雜,可以將問題分解來看,和高中數學題的感覺一樣 1.求任意一組組合的最小的保護值 的最大值 2.求在改最大組合的情況下的,求最小的工資和,和某圖論一樣的思路。解題思路 第乙個揹包 任意組合 抽象成模板 在n個應聘者中選x人使得看守m個倉...
紫書 習題 8 15 UVa 1617 (貪心)
先排序,然後每個線段先放右端點,然後往下放,如果不能放就整體往左移動,當不能往左移動的時候就ans 開始下乙個整塊。判斷能不能向左移動要用乙個變數儲存每個已經放了的區間中線段與左端點距離的最小值。include include define rep i,a,b for int i a i b i u...