1. 程式人生 > >Luogu P1094 紀念品分組

Luogu P1094 紀念品分組

eat style 匹配 assign image 證明 tar 我想 們的

Description

詳見https://www.luogu.org/problem/show?pid=1094

Solution

> -------
這是一道不錯的貪心,雖然代碼很短,但是證明還是挺考思維的
> -------
先從大到小排序
> -------

剛開始想將最大的和他能搭配的最大的搭配,比如圖中a可以和c和d,但是我想選擇c,

技術分享
> -------
但是仔細一想其實沒這個必要,
因為 ,如果a>b,c>d 而且 a+c<=w 那麽b+c<=w 也就是說無論 a&c,b&d 或a&d,b&c都是兩種

技術分享
於是我們的搭配完全沒有必要交叉,交叉的結果也是等於不交叉的

> -------
所以我們可以從外向內匹配【保證不交叉】
如果可以匹配就匹配不能就自己放一個盒子

Codes

 1 var
 2   n,w,i,j,ans:Longint;
 3   a:array[1..30000] of longint;
 4   b:array[1..30000] of Boolean;
 5 
 6 procedure qsort(l,r: longint);
 7 var
 8    i,j,x: longint;
 9    y:longint;
10 begin
11     i:=l;   j:=r;
12     x:=a[(l+r) div
2]; 13 repeat 14 while (a[i]>x) do inc(i); 15 while (x>a[j]) do dec(j); 16 if not(i>j) then 17 begin 18 y:=a[i]; a[i]:=a[j]; a[j]:=y; 19 inc(i); j:=j-1; 20 end; 21 until i>j; 22 if l<j then qsort(l,j); 23 if i<r then
qsort(i,r); 24 end; 25 26 begin 27 // assign(input,t.in); assign(output,t.out); 28 reset(input); rewrite(output); 29 30 readln(w); 31 readln(n); 32 for i:= 1 to n do readln(a[i]); 33 34 qsort(1,n); 35 36 i:=1; j:=n; 37 while i<=j do 38 begin 39 if a[i]+a[j]<=w then dec(j) ; 40 inc(i); 41 ans:=ans+1; 42 end; 43 44 writeln(ans); 45 close(input); close(output); 46 end.

Luogu P1094 紀念品分組