vijos-p1456 2008.11.9

vijos-p1456 2008.11.9

我心得:搜索的优化会有很多种,要从中挑选空间和时间都最优的

描述 Description  

n个人在做传递物品的游戏,编号为1-n。

游戏规则是这样的:开始时物品可以在任意一人手上,他可把物品传递给其他人中的任意一位;下一个人可以传递给未接过物品的任意一人。

即物品只能经过同一个人一次,而且每次传递过程都有一个代价;不同的人传给不同的人的代价值之间没有联系;

求当物品经过所有n个人后,整个过程的总代价是多少。

输入格式 Input Format 

第一行为n,表示共有n个人(16>=n>=2);

以下为n*n的矩阵,第i+1行、第j列表示物品从编号为i的人传递到编号为j的人所花费的代价,特别的有第i+1行、第i列为-1(因为物品不能自己传给自己),其他数据均为正整数(<=10000)。

(对于50%的数据,n<=11)。

输出格式 Output Format  

一个数,为最小的代价总和。

样例输入 Sample Input  

2

-19794

2724–1

样例输出 Sample Output  

2724

 

心得:今天终于见识了记忆化搜索,要初始化,何在搜索中的运算

第一种搜索:80分,改变了搜索顺序,把代价值从小到大排序,从小的开始搜,剪枝的力度还不够,但仍不能ac

program p1456;
type arr=array[1..16,1..2]of longint;
var a:array[1..16]of arr;
    ans,i,j,n,max:longint;
    f1,f2:text;
    b:array[1..16]of boolean;
    h:array[1..16]of longint;
procedure qsort(var p:arr);
  procedure sort(l,r: longint);
     var
        i,j,x,y,t1,t2,nn: longint;
     begin
        i:=l;
        j:=r;
        nn:=random(j-i+1)+i;
        x:=p[nn,1];
        repeat
          while p[i,1]j) then
            begin
               y:=p[i,1];
               t2:=p[i,2];
               p[i,1]:=p[j,1];
               p[i,2]:=p[j,2];
               p[j,1]:=y;
               p[j,2]:=t2;
               inc(i);
               dec(j);
            end;
        until i>j;
        if lans then exit;
  if (t=n+1)and(max

Program2,用到了传说中的记忆化搜索,我没想到,问了别的大牛

program abc;
const maxn=17;
var n:longint;
      g:array[0..maxn,0..maxn]of longint;
      v:array[0..maxn]of boolean;
      tot,ans:longint;
 procedure init;
 var i,j:longint;
 begin
   ans:=maxlongint;
   fillchar(v,sizeof(v),1);
   fillchar(g,sizeof(g),$6f);
   readln(n);
   for i:=1 to n do
     begin
       for j:=1 to n do
         begin
           read(g[i,j]);
           if (g[i,j]j)  then g[j,0]:=g[i,j];
//这里g[j,0]存放,到达j这个人的最小值,用于以后的剪枝用
          end;
         end;
 end;
 procedure try(step,x:longint);
 var i,rest:longint;
 begin
   if step>n then
     begin
       if tot=ans then exit;//这里用到了刚才的初始化数据,找到还没有到达的节点,在目前的和上累计他们需要的最小代价,如果比当前的最小解ans还大,那就放弃,exit
      for i:=1 to n do
        if v[i] then
          begin
            v[i]:=false;
            inc(tot,g[x,i]);
            try(step+1,i);
            v[i]:=true;
            dec(tot,g[x,i]);
          end;
end;
procedure main;
var i:longint;
begin
  for i:=1 to n do
    begin
      tot:=0;v[i]:=false;
      try(2,i);
      v[i]:=true;
     end;
 end;
 begin
   init;
   main;
   writeln(ans);
  end.



你可能感兴趣的:(VIJOS)