Nguồn đề bài: http://vn.spoj.com/problems/DHEXP/
1. Đề thi duyên hải môn tin học khối 10 2015
Một dãy gồm n số nguyên không âm a1, a2,…, an được viết thành một hàng ngang, giữa hai số liên tiếp có một khoảng trắng, như vậy có tất cả (n-1) khoảng trắng. Người ta muốn đặt k dấu cộng và (n-1-k) dấu trừ vào (n-1) khoảng trắng đó để nhận được một biểu thức có giá trị lớn nhất.
Ví dụ, với dãy gồm 5 số nguyên 28, 9, 5, 1, 69 và k = 2 thì cách đặt 28+9-5-1+69 là biểu thức có giá trị lớn nhất.
Yêu cầu: Cho dãy gồm n số nguyên không âm a1, a2,…, an và số nguyên dương k, hãy tìm cách đặt kdấu cộng và (n-1-k) dấu trừ vào (n-1) khoảng trắng để nhận được một biểu thức có giá trị lớn nhất.
Input
– Dòng đầu chứa hai số nguyên dương n, k (k < n);
– Dòng thứ hai chứa n số nguyên không âm a1, a2,…, an (an ≤ 106)
Output
Một số nguyên là giá trị của biểu thức đạt được.
Example
Input:
5 2
28 9 5 1 69
Output:
100
Ghi chú:
- Có 50% số test ứng với 50% số điểm có n ≤ 105 và k = 1;
- Có 50% số test còn lại ứng với 50% số điểm có n ≤ 105;
2. Hướng dẫn DHEXP spoj
– Gợi ý dùng thuật toán tham lam, điền các dấu cộng vào k số lớn nhất. các số còn lại là dấu trừ.
Hướng dẫn cách làm
các bạn có thể dùng Quicksort để sắp xếp. sau đó chọn ra k số để đặt dấu trừ. lưu ý là không đặt dấu cho số đầu tiên.
3. Code tham khảo DHEXP spoj
const fi='';
nmax=100000;
type data=longint;
var
f:text;
A,id:array[0..nmax+1] of data;
n,k:data;
res:int64;
procedure docfile;
var i,j:data;
begin
assign(f,fi); reset(f);
readln(f,n,k);
res:=0;
for i:=1 to n do
begin
read(f,a[i]);
id[i]:=i;
res:=res+a[i];
end;
close(f);
end;
procedure swap(var a,b:data);
var z:data;
begin
z:=a;
a:=b;
b:=z;
end;
procedure sort(l,r: longint);
var
i,j,x,y: longint;
begin
i:=l;
j:=r;
x:=a[(l+r) div 2];
repeat
while a[i]<x do inc(i);
while x<a[j] do dec(j);
if not(i>j) then
begin
y:=a[i];
a[i]:=a[j];
a[j]:=y;
swap(id[i],id[j]);
inc(i);
j:=j-1;
end;
until i>j;
if l<j then
sort(l,j);
if i<r then
sort(i,r);
end;
procedure xuli;
var i,j:data;
begin
sort(1,n);
k:=n-1-k;
for i:=1 to n do
if id[i]<>1 then
begin
if k=0 then break;
res:=res-2*a[i];
dec(k);
if k=0 then break;
end;
writeln(res);
end;
begin
docfile;
xuli;
end.