解题报告 购物

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.

 

 

posted @ 2011-10-15 16:44  木小漾  阅读(434)  评论(1编辑  收藏  举报