1. 程式人生 > 其它 >貪心刷題小結

貪心刷題小結

昨天晚上做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;
    
}