P4447 AHOI2018初中組 分組 貪心

2022-06-25 01:54:11 字數 1217 閱讀 6411

p4447 [ahoi2018初中組]分組

首先想到對資料進行某種排序後順序處理,sort(因此是公升序)就可以了.(一開始看到演算法標籤裡有個佇列就開了優先佇列,後來發現沒必要而且讓**看起來很複雜)

最初想到的處理方式是遍歷公升序排序後的每個資料,對於每個資料遍歷所有隊伍(用二維陣列儲存所有隊伍的所有成員實力),如果當前隊伍的最後一名成員的實力等於當前資料+1,則把這個資料加入到此隊伍中.否則(當前資料等於最後一名的成員實力或大於其實力+1)就需要就新建一支隊伍.最後計算並輸出最少人組的人數.

大體思路是正確的,卻只過了4/10個點.

這是昨天晚上23:00發生的事情,於是只能去睡覺了.今天醒來忍不住去看了題解,發現漏掉乙個細節處理.

如果輸入

612

3234

輸出2,隊伍為1234和23

正確答案是3,隊伍為123和234

如果遍歷隊伍時發現可行隊伍就立即入隊,那麼就不能保證人數最少的隊伍人數取最大值.所以必須遍歷所有隊伍後把當前成員加入到人數最少的可行隊伍.於是開了個pos[100000]記錄發現的可行隊伍,又來個(偽push)pushmin函式處理這個操作.最終成功的從wa走向tle.

接下來是貪心思想的體現,我貪心地再看題解.發現想要實現每次都插入到人數最少的隊伍只需要倒序遍歷已有隊伍,發現可行時立即插入就可以了(易證).雖然仍然是o(n2),但迴圈被簡化了不止一點兩點(這題資料很強).

此外,還意識到儲存隊伍只需要儲存隊伍人數len和最後一名成員的實力top就可以了,效率大幅提公升,**也簡潔很多.

第四道綠題,雖然是看題解水過來的,以後盡力,但也不要死磕.

#include

#include

#include

#include

using namespace std;

int n, s[100010];

int idx, ans = 100000;

struct s

t[100010];

int main()

if(bad)

}for(int i = 0; i < idx; i++)

ans = min(ans, t[i].len);

printf("%d\n", ans);

return 0;

}

P4447 AHOI2018初中組 分組(貪心

傳送門 思路 貪心。將陣列從小到大排好序後,用優先佇列維護每個組的當前最大實力值和人數,按照實力值為第一關鍵字,人數為第二關鍵字排序。討論一下 因為我們是按實力值從小到大排序的,所以不會出現a i a i a i 隊首實力值的情況。1.若a i a i a i 不等於當前隊首實力值 1 1 1,則該...

洛谷 P4447 AHOI2018初中組 分組

題目 總共有n個隊員,每個人都有乙個實力值a i 把n個隊員分成若干個小組。要求分成的每個小組的隊員實力值連續,同時,乙個隊不需要兩個實力相同的選手。給出乙個合法的分組方案,滿足所有人都恰好分到乙個小組。使得人數最少的組人數最多,輸出人數最少的組人數的最大值。注意 實力值可能是負數,分組的數量沒有限...

洛谷 P4447 AHOI2018初中組 分組

題目 一開始沒讀懂題,直接排序 模擬找最短長度,像 6 1 2 3 1 2 3這組資料這種查詢方法結果是1,正解是3 include include include include include include include include using namespace std typedef...