「日常訓練」Woodcutters(Codeforces Round 303 Div.2 C)
阿新 • • 發佈:2018-10-01
答案 cpp break lse 策略 -c else if bool else 棵樹到第\(n\)棵樹如果挨個往左倒正好完美覆蓋。那麽這種情況下你第\(i-1\)棵樹如果可以往右倒照樣可以往右倒,因為每棵樹的倒下只影響另外左右一個樹,那麽我大不了第\(i\)棵樹不倒,我的答案不會更差。這樣就確定了貪心策略的正確性。
這題慘遭被卡。。卡了一個小時,太真實了。
題意與分析 (Codeforces 545C)
題意:給定\(n\)棵樹,在\(x\)位置,高為\(h\),然後可以左倒右倒,然後倒下去會占據\([x-h,x]\)或者\([x,x+h]\)區間,如果不砍伐,占據\([x,x]\)區域。
問你最多砍多少棵樹,砍樹的條件是倒下去後占有的區間不能被其他樹占據。
分析:在這條題目的條件下,這是一個傻逼貪心題。(然後我讀錯兩次題目,怎麽也想不出來貪心策略。。。。)
很簡單的策略:能往左倒往左倒,能往右倒往右倒。因為樹的倒下無論如何只會影響額外的一棵樹!!(換句話說,如果說倒下的區間不用考慮樹的存在,就很有意思了)舉個例子,考慮一種極端情況:第\(i\)
代碼
#include <bits/stdc++.h> #define MP make_pair #define PB push_back #define fi first #define se second #define ZERO(x) memset((x), 0, sizeof(x)) #define ALL(x) (x).begin(),(x).end() #define rep(i, a, b) for (repType i = (a); i <= (b); ++i) #define per(i, a, b) for (repType i = (a); i >= (b); --i) #define QUICKIO ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); using namespace std; using ll=long long; using repType=int; int main() { int n; cin>>n; pair<int,int> tree[100005]; rep(i,1,n) cin>>tree[i].fi>>tree[i].se; int cnt=0; int npos=0,ntree=1; int cut[100005]; ZERO(cut); rep(i,1,n) { int l_boundary=tree[i].fi-tree[i].se, r_boundary=tree[i].fi+tree[i].se; bool lok=true; per(j,i-1,1) { if(tree[j].fi>=l_boundary || (cut[j]==2&&tree[j].fi+tree[j].se>=l_boundary)) { lok=false; break; } if(tree[j].fi+tree[j].se<l_boundary) break; } if(lok) { cut[i]=1; continue; } bool rok=true; rep(j,i+1,n) { if(tree[j].fi>r_boundary) break; else if(tree[j].fi<=r_boundary) {rok=false; break;} } if(rok) cut[i]=2; } int ans=0; rep(i,1,n) if(cut[i]) ans++; cout<<ans<<endl; return 0; }
「日常訓練」Woodcutters(Codeforces Round 303 Div.2 C)