【BZOJ】1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚(dp/线段树)
http://www.lydsy.com/JudgeOnline/problem.php?id=1672
dp很好想,但是是n^2的。。但是可以水過。。(5s啊。。)
按左端點排序后
f[i]表示取第i個的最小費用
f[i]=min(f[j])+w[i] 當j的結束時間>=i的開始時間-1
答案就是所有的i滿足i的結束時間>=結束時間-1
#include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream> #include <algorithm> #include <queue> using namespace std; #define rep(i, n) for(int i=0; i<(n); ++i) #define for1(i,a,n) for(int i=(a);i<=(n);++i) #define for2(i,a,n) for(int i=(a);i<(n);++i) #define for3(i,a,n) for(int i=(a);i>=(n);--i) #define for4(i,a,n) for(int i=(a);i>(n);--i) #define CC(i,a) memset(i,a,sizeof(i)) #define read(a) a=getint() #define print(a) printf("%d", a) #define dbg(x) cout << #x << " = " << x << endl #define printarr(a, n, m) rep(aaa, n) { rep(bbb, m) cout << a[aaa][bbb]; cout << endl; } inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; } inline const int max(const int &a, const int &b) { return a>b?a:b; } inline const int min(const int &a, const int &b) { return a<b?a:b; }const int N=10005; int f[N], n, ans=~0u>>1; struct dat { int x, y, w; }a[N]; const bool cmp(const dat &x, const dat &y) { return x.x==y.x ? x.y<y.y : x.x<y.x; } int main() {read(n); a[0].y=getint()-1; a[n+1].x=getint()+1;for1(i, 1, n) read(a[i].x), read(a[i].y), read(a[i].w);sort(a+1, a+1+n, cmp);CC(f, 0x3f);f[0]=0;for1(i, 1, n+1) {int s=a[i].x, w=a[i].w;rep(j, i) if(s-1<=a[j].y) f[i]=min(f[i], f[j]+w);}for1(i, 1, n) if(a[i].y>=a[n+1].x-1 && ans>f[i]) ans=f[i];ans=min(ans, f[n+1]);if(ans==f[n+2]) ans=-1;print(ans);return 0; }?
線段樹:
(調試了n久啊。。果然不能看別人代碼對著抄。。。。。)
對于一個點i,我們更新它時要用它所在的區間(開始時間-1到結束時間)有沒有已經接上的(即更新過的)。
所以我們按左端點排序后
依次更新線段樹。(單點更新即可,按結束時間更新, 首先要詢問本區間,然后接上)
然后詢問的時候直接詢問本區間的答案。
最后答案就是end的單點詢問
#include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream> #include <algorithm> #include <queue> using namespace std; #define rep(i, n) for(int i=0; i<(n); ++i) #define for1(i,a,n) for(int i=(a);i<=(n);++i) #define for2(i,a,n) for(int i=(a);i<(n);++i) #define for3(i,a,n) for(int i=(a);i>=(n);--i) #define for4(i,a,n) for(int i=(a);i>(n);--i) #define CC(i,a) memset(i,a,sizeof(i)) #define read(a) a=getint() #define print(a) printf("%d", a) #define dbg(x) cout << #x << " = " << x << endl #define printarr(a, n, m) rep(aaa, n) { rep(bbb, m) cout << a[aaa][bbb]; cout << endl; } inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; } inline const int max(const int &a, const int &b) { return a>b?a:b; } inline const int min(const int &a, const int &b) { return a<b?a:b; } #define lc x<<1 #define rc x<<1|1 #define MID (l+r)>>1 #define lson l, m, lc #define rson m+1, r, rcconst int N=10005, oo=~0u>>1; int n, st, en; int ans; struct dat { int x, y, w; }a[N]; struct node { int mn; }t[500005]; const bool cmp(const dat &x, const dat &y) { return x.x<y.x; } void pushup(int x) { t[x].mn=min(t[lc].mn, t[rc].mn); } void build(int l, int r, int x) {t[x].mn=oo;if(l==r) return;int m=MID;build(lson); build(rson); } void update(int l, int r, int x, const int &key, const int &R) {if(l==r) {t[x].mn=min(key, t[x].mn);return;}int m=MID;if(R<=m) update(lson, key, R); else update(rson, key, R);pushup(x); } int query(int l, int r, int x, const int &L, const int &R) {if(L<=l && r<=R) return t[x].mn;int m=MID; int mn=oo;if(L<=m) mn=min(mn, query(lson, L, R)); if(m<R) mn=min(mn, query(rson, L, R));return mn; } int main() {read(n); read(st); read(en);for1(i, 1, n) read(a[i].x), read(a[i].y), read(a[i].w);sort(a+1, a+1+n, cmp);build(st, en, 1);for1(i, 1, n) {if(a[i].x<=st) ans=0; else ans=query(st, en, 1, a[i].x-1, a[i].y);if(ans!=oo) update(st, en, 1, ans+a[i].w, a[i].y);}ans=query(st, en, 1, en, en);if(ans==oo) puts("-1");else printf("%d", ans);return 0; }?
?
?
?
Description
Farmer John's cows, pampered since birth, have reached new heights of fastidiousness. They now require their barn to be immaculate. Farmer John, the most obliging of farmers, has no choice but hire some of the cows to clean the barn. Farmer John has N (1 <= N <= 10,000) cows who are willing to do some cleaning. Because dust falls continuously, the cows require that the farm be continuously cleaned during the workday, which runs from second number M to second number E during the day (0 <= M <= E <= 86,399). Note that the total number of seconds during which cleaning is to take place is E-M+1. During any given second M..E, at least one cow must be cleaning. Each cow has submitted a job application indicating her willingness to work during a certain interval T1..T2 (where M <= T1 <= T2 <= E) for a certain salary of S (where 0 <= S <= 500,000). Note that a cow who indicated the interval 10..20 would work for 11 seconds, not 10. Farmer John must either accept or reject each individual application; he may NOT ask a cow to work only a fraction of the time it indicated and receive a corresponding fraction of the salary. Find a schedule in which every second of the workday is covered by at least one cow and which minimizes the total salary that goes to the cows.
約翰的奶牛們從小嬌生慣養,她們無法容忍牛棚里的任何臟東西.約翰 發現,如果要使這群有潔癖的奶牛滿意,他不得不雇傭她們中的一些來清掃牛棚,?約翰的奶牛中有N(1≤N≤10000)頭愿意通過清掃牛棚來掙一些零花 錢.由于在某個時段中奶牛們會在牛棚里隨時隨地地亂扔垃圾,自然地,她們要求在這段時間里,無論什么時候至少要有一頭奶牛正在打掃.需要打掃的時段從某一 天的第M秒開始,到第E秒結束f0≤M≤E≤86399).注意這里的秒是指時間段而不是時間點,也就是說,每天需要打掃的總時間是E-M+I秒.?約翰已經從每頭牛那里得到了她們愿意接受的工作計劃:對于某一頭牛,她每天都愿意在笫 Ti,.T2秒的時間段內工作(M≤Ti≤馬≤E),所要求的報酬是S美元(0≤S≤500000).與需打掃時段的描述一樣,如果一頭奶牛愿意工作的時 段是每天的第10_20秒,那她總共工作的時間是11秒,而不是10秒.約翰一旦決定雇傭某一頭奶牛,就必須付給她全額的工資,而不能只讓她工作一段時 間,然后再按這段時間在她愿意工作的總時間中所占的百分比來決定她的工資.現在請你幫約翰決定該雇傭哪些奶牛以保持牛棚的清潔,當然,在能讓奶牛們滿意的 前提下,約翰希望使總花費盡量小.Input
* Line 1: Three space-separated integers: N, M, and E. * Lines 2..N+1: Line i+1 describes cow i's schedule with three space-separated integers: T1, T2, and S.
第1行:3個正整數N,M,E,用空格隔開. 第2到N+1行:第i+l行給出了編號為i的奶牛的工作計劃,即3個用空格隔開的正整數Ti,T2,S.Output
* Line 1: a single integer that is either the minimum total salary to get the barn cleaned or else -1 if it is impossible to clean the barn.
輸出一個整數,表示約翰需要為牛棚清理工作支付的最少費用.如果清理工作不可能完成, 那么輸出-1.Sample Input
3 0 4 //三頭牛,要打掃從0到4號stall0 2 3 //一號牛,從0號stall打掃到2號,工資為3
3 4 2
0 0 1
INPUT DETAILS:
FJ has three cows, and the barn needs to be cleaned from second 0 to second
4. The first cow is willing to work during seconds 0, 1, and 2 for a total
salary of 3, etc.
Sample Output
5HINT
約翰有3頭牛,牛棚在第0秒到第4秒之間需要打掃.第1頭牛想要在第0,1,2秒內工作,為此她要求的報酬是3美元.其余的依此類推.????約翰雇傭前兩頭牛清掃牛棚,可以只花5美元就完成一整天的清掃.
Source
Silver
總結
以上是生活随笔為你收集整理的【BZOJ】1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚(dp/线段树)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSS3实战开发:使用CSS3实现pho
- 下一篇: cocos2dx[3.2](5) ——入