1. 程式人生 > >淺談貪心算法2

淺談貪心算法2

我只 spa 貪心 n) problem 但是 如果 滿足 分數

這是我寫的貪心5章中的第2章,這一章,我想講一講在OI競賽中,貪心直覺的重要性

在考場上,因為考前作息,心理狀態甚至生理狀態,都會影響我們的成績,所以考場上分析問題的能力可能會大有縮水,所以我認為,普及組想拿一等獎,平時至少要有提高組一等獎或二等獎的水準

不過講這些好像跑題了,想在考場上寫對貪心算法,對一個選手的要求是很高的,那麽,除了可怕的數學建模能力,就真的沒有解決貪心的方法了?

答案是:直覺

https://www.luogu.org/problemnew/show/P4447

也許正如那些大神所說的,在2018的安徽省選中,我只在現場AC了兩題,一道紅題,一道綠題(也就是上面這題),平時都能切切藍題的,但是在考場上,T2(一到藍題)只拿到了40分的暴力,主要就是靠這題來扳回分數

大概一個小時,拿下了T1和T2(T2寫的暴力),看了一下題面,感覺這題還是可做的,於是開始茍正解

我們是用n表示總人數,a[]這個數組來表示某個隊員的實力的。那麽我們再把每個組裏的人數放入f[]數組,num表示當前是第幾個組,而用b[]數組表示某組最大的能力值。首先我們要將所有人按他們的能力值從小到大排序,然後再進行處理:

1、如果存在,也就是使b[j]+1=a[i],那麽可以直接插入到J組後面(這裏無需考慮是不是最大值,因為前面排過序了,所以必定為最大的),為了能讓最小的人數盡可能大,那麽應該插入到那個滿足條件人數最少的組

2、否則a[i]不可以插入到任何一組,那麽就必須新增一組

這也正是我半個小時思考後的結果,於是開始碼代碼,(為了防止出鍋),我花費了1H寫這題,因為這個問題具備單調性,所以本來準備寫完T4後再加一波二分查找的,但是T4的正解好像沒茍出來,於是就把這份代碼交上去了(以下碼風較醜,因為是考場上寫的)

#include<cstdio>
#include<algorithm>
using namespace std;
int a[100005];
struct NODE{
    int lr;
    int ln;
}node[100005];
int main(){
//freopen ("division.in","r",stdin);
//freopen ("division.out","w",stdout);
int n;
    scanf ("%d",&n);
    for (int i=1;i<=n;++i){
        scanf ("%d",&a[i]);
    }
    sort (a+1,a+1+n);
    int len=1,ans=1<<30,j;
    node[1].lr=a[1];node[1].ln=1;
    for (register int i=2;i<=n;++i){
        int find1=1<<30,find2=0;
        for (j=1;j<=len;++j){
            if ((a[i]-node[j].lr==1)||(a[i]-node[j].lr==-1)&&node[j].ln<find1){
                find1=node[j].ln;
                find2=j;
            }
        }
        if (find1==(1<<30)){
            ++len;
            node[len].ln=1;
            node[len].lr=a[i];
        }
        else{
            node[find2].ln++;
            node[find2].lr=a[i];
        }
    }	
    for (register int i=1;i<=len;++i){
        if (node[i].ln<ans) ans=node[i].ln;
    }
    printf ("%d\n",ans);
return 0;
}

然後,我就在考場上切了這題,這種貪心我也不會證明,但是,直覺讓我寫對了,全班也就兩個人AC(%%%ZJFjulao)

強化直覺,就是要靠刷一些貪心來訓練直覺,當然也要有數學建模的基礎

淺談貪心算法2