貪心刷題小結
阿新 • • 發佈:2021-10-19
昨天晚上做LG秋令營題單時發現自己已經不會貪心了,所以就找了幾道水題來練練手。
不是秋令營的題,我沒有洩題
CF482A:(其實是構造?emmm分不清貪心與構造)若k=1,我們只需要按順序輸出就行了。k≠1呢?很自然的想到只需要在前k+1個數構造出k個差,後面直接順序輸出。因為k個差不能相等,所以我們可以一大一小的分配數。
即1,n,2,n-1...這樣。
程式碼:
#include<bits/stdc++.h> using namespace std; #define il inline #define ll long long il int read() { int s=0,w=1; char ch=getchar(); while(ch<'0' || ch>'9') { if(ch=='-') w=-1; ch=getchar();} while(ch>='0' && ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w; } const int N=1e5+5; int n,k; int main() { n=read(); k=read(); int js=1,i=1,j=n; for(;js<=k;js++) {if(js % 2) { printf("%d ",i); i++; } else { printf("%d ",j); j--; } } if(js % 2) for(;js<=n;js++) { printf("%d ",j); j--; } else { for(;js<=n;js++) { printf("%d",i); i++; } } return 0; }
CF545C:第一反應是按樹高排序,優先倒低的的樹,因為覆蓋面積小所以期望收益大。但顯然這樣是錯誤的,因為樹向左和向右倒的收益不同。那怎麼辦呢?換個思路,按位置排序,第一棵樹向左倒,最後一棵樹向右倒(這就不解釋了)。對於中間的樹,我們自然的想先讓它向左倒,如果能到下的話,自然最優,如果不能倒下,我們再儘量讓它向右倒。我們來分類討論,如果第i棵樹向右倒後,第i+1棵樹還能向左倒,明顯最優;如果第i+1棵樹不能向左倒,此時我們若選擇讓第i棵樹不倒而第i+1棵樹向左倒,相比於直接讓第i棵樹向右倒,第i+1棵樹失去了向右倒的機會,也就是說,這個方案劣於後者。這樣,我們就證明了這個貪心的正確性。
程式碼:
#include<bits/stdc++.h> using namespace std; #define il inline #define ll long long il int read() { int s=0,w=1; char ch=getchar(); while(ch<'0' || ch>'9') { if(ch=='-') w=-1; ch=getchar();} while(ch>='0' && ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w; } const int N=1e5+10; int n; struct tree{ int x,h; } t[N]; bool cmp(tree a,tree b) { return a.x <b.x; } int ans; int main() { n=read(); for(int i=1;i<=n;i++) t[i].x=read(),t[i].h=read(); if(n==1) { printf("1"); return 0; } sort(t+1,t+n+1,cmp); ans=2; for(int i=2;i<n;i++) { if(t[i].x - t[i].h > t[i-1].x) { ans++; continue; } if(t[i].x + t[i].h < t[i+1].x) { ans++; t[i].x+=t[i].h; continue; } } printf("%d\n",ans); return 0; }