1. 题目
购物shopping
【问题描述】
小T和小L都很喜欢购物,但是,众所周知,小T和小L都很懒,因此,在这么热的天,他们宁可在淘宝上买东西。现在,货架上有N件物品,由于小T和小L共用一台电脑,他们决定轮流购买自己喜欢的东西。由于小T和小L的审美完全不同,因此,每件物品对小T的价值为A_i,对小L的价值为B_i。因为小L和小T是好朋友,因此他们在满足自己利益的时候也会为别人着想。小T总是会选择对自己价值最大的物品,如果有多个,则选择其中对小L价值最小的。而小L就聪明很多(因为小L会算!= =||),他总是选择会使自己最后得到的物品总价值最多的物品,如果有多个,他会选择使得小L最后得到总价值也最多的物品。
现在,要求聪明的你帮助小L和小T计算按照他们的策略最后分别得到的物品的价值。
【输入格式】
第一行一个数N表示物品数。
第二行为“L”或者“T”,表示L或者T先选取物品。
第三到第N+2行,每行两个数A_i和B_i
【输出格式】
一行用空格隔开两个数P,Q分别表示小T和小L最后得到物品的总价值。
【样例输入】
4
T
100 80
70 80
50 80
30 50
【样例输出】
170 130
数据范围:
N<=100
2. 算法
啊啊,怎么又是一道语文题。
小 T 是贪心,小 L 是动规,合起来还是动规。。。。。。怎么越讲越乱?
不说了,上代码。
3. 注意事项
读题去!
4. 代码
记忆化搜索 (作者不详)
var n,i,j,max,t,k,vt,vl:longint;
hash:array[1..100]of boolean;
a,b:array[1..100]of longint;
f:char;
begin //记忆化搜索
assign(input,'Shopping.in');reset(input);
assign(output,'Shopping.out');rewrite(output);
readln(n);
readln(f);
for i:=1 to n do
readln(a[i],b[i]);
for i:=1 to n do hash[i]:=true;
for i:=1 to n do
begin
if f='T' then
begin
max:=0;t:=maxlongint;
for j:=1 to n do
if hash[j] then
begin
if a[j]=max then
if b[j]<t then
begin
b[j]:=t;
k:=j;
end;
if a[j]>max then
begin
max:=a[j];
t:=b[j];
k:=j;
end;
end;
f:='L';vt:=vt+max;
hash[k]:=false;
end;
if f='L' then
begin
max:=0;t:=maxlongint;
for j:=1 to n do
if hash[j] then
begin
if b[j]=max then
if a[j]<t then
begin
a[j]:=t;
k:=j;
end;
if b[j]>max then
begin
max:=b[j];
t:=a[j];
k:=j;
end;
end;
f:='T';vl:=vl+max;
hash[k]:=false;
end
end;
writeln(vt,' ',vl);
close(input);close(output);
End.
DP (魂之挽歌)
program shopping;
var a,b:array[1..101]of longint;
f,g:array[0..101,0..100,0..100]of longint;
m,n,i,j,k,t1,t2,t:longint;
c:char;
function max(a,b:longint):longint;
begin
if a>b then exit(a)
else exit(b);
end;
begin //DP
assign(input,'shopping.in');reset(input);
assign(output,'shopping.out');rewrite(output);
readln(n);
readln(c);
for i:=1 to n do readln(a[i],b[i]);
for i:=1 to n-1 do
for j:=i+1 to n do
if ((a[i]=a[j])and(b[i]<b[j]))or(a[i]<a[j]) then begin
t:=a[i];a[i]:=a[j];a[j]:=t;
t:=b[i];b[i]:=b[j];b[j]:=t;
end;
if c='L' then
begin
inc(n);
for i:=n downto 2 do
begin
a[i]:=a[i-1];
b[i]:=b[i-1];
end;
a[1]:=0;b[1]:=0;
end;
j:=n div 2;
i:=n-j;
m:=i;n:=j;
for i:=1 to m+n do
for j:=1 to m do
begin
k:=i-j;
if k<0 then continue;
t1:=0;t2:=0;
if j-1>=k then t1:=f[i-1,j-1,k];
if k>0 then t2:=f[i-1,j,k-1]+b[j+k];
f[i,j,k]:=max(t1,t2);
if (t2>=t1)and(k>0) then g[i,j,k]:=g[i-1,j,k-1]
else g[i,j,k]:=g[i-1,j-1,k]+a[j+k];
end;
writeln(g[m+n,m,n],' ',f[m+n,m,n]);
close(input);close(output);
end.