POJ 1952(最长不下降子序列的个数)

求一个序列的最长不下降子序列的长度,与个数(相同数列算1个)

关键是如何判重。

显然如果之前有一个尾数相同且长度相同的序列,哪么后一个包含前一个所有可能的序列相同的序列,故将前一个序列删除(重复)

Program P1952;
var
   n,i,j,ans:longint;
   a,len,f,path:array[1..5000] of longint;
begin
   read(n);
   for i:=1 to n do read(a[i]);
   for i:=1 to n do
   begin
      len[i]:=1;
      f[i]:=1;
      path[i]:=i;
      for j:=i-1 downto 1 do
         if (a[j]>a[i]) and (len[j]+1>len[i]) then
         begin
            len[i]:=len[j]+1;
            f[i]:=f[j];
         end
         else if (a[j]>a[i]) and (len[j]+1=len[i]) then inc(f[i],f[j]);


      for j:=1 to i-1 do
         if (a[i]=a[j]) and (len[i]=len[j]) then f[j]:=0;



   end;
   j:=0;
   for i:=1 to n do if len[i]>j then j:=len[i];
   ans:=0;
   for i:=1 to n do if len[i]=j then inc(ans,f[i]);

   writeln(j,' ',ans);


end.

POJ 1951(空串特判)

这题的教训是 要特判空串

Program P1951;
var
   s:string;
   len,i,j:longint;
   b:array[0..10000] of boolean;
function isdight(x:longint):boolean;
begin
   if (x>=65) and (x<=90) then exit(false);
   if (x>=97) and (x<=122) then exit(false);
   exit(true);

end;
begin
   readln(s);
   fillchar(b,sizeof(b),false);
   b[ord('a')]:=true;
   b[ord('e')]:=true;
   b[ord('i')]:=true;
   b[ord('o')]:=true;
   b[ord('u')]:=true;
   b[ord('A')]:=true;
   b[ord('E')]:=true;
   b[ord('I')]:=true;
   b[ord('O')]:=true;
   b[ord('U')]:=true;

   i:=1;
   while i<=length(s) do
   begin
      if b[ord(s[i])] and not(isdight(ord(s[i]))) then delete(s,i,1)
      else
      begin
         b[ord(s[i])]:=true;
         inc(i);

      end;
   end;


   while (s[1]=' ') and (length(s)>=1) do delete(s,1,1);
   while (s[length(s)]=' ') and (length(s)>=1) do delete(s,length(s),1);
   i:=pos('  ',s);
   while i<>0 do
   begin
      delete(s,i,1);
      i:=pos('  ',s);
   end;
   i:=pos(' .',s);
   while i<>0 do
   begin
      delete(s,i,1);
      i:=pos(' .',s);
   end;
   i:=pos(' ,',s);
   while i<>0 do
   begin
      delete(s,i,1);
      i:=pos(' ,',s);
   end;
   i:=pos(' ?',s);
   while i<>0 do
   begin
      delete(s,i,1);
      i:=pos(' ?',s);
   end;



   writeln(s);

end.

POJ 1950(不打表做法)

这题就是搜……

注意设定maxn 要不然肯定爆 maxn=1*10^最大位数/2 1234..89-11121314这样的

Program aa;
const
   maxn=1000000000000000;
var
   n,t:longint;
   a:array[1..15] of char;
procedure dfs(l,sum,res,bl:int64);
var
   i,j:longint;
begin
   if l=n then
   begin
      res:=res+bl*sum;
      if res=0 then
      begin
         inc(t);
         if t<=20 then
         begin
            for i:=1 to n-1 do write(i,' ',a[i],' ');
            writeln(n);


         end;
      end;


      exit;
   end;

   a[l]:='+';
   dfs(l+1,l+1,res+bl*sum,1);
   a[l]:='-';
   dfs(l+1,l+1,res+bl*sum,-1);
   a[l]:='.';
   if sum<=maxn then
   if l+1<=9 then
      dfs(l+1,sum*10+(l+1),res,bl)
   else
      dfs(l+1,sum*100+(l+1),res,bl);


end;
begin
 {  assign(output,'a.pas');
   rewrite(output);
  }
   read(n);
   t:=0;
   dfs(1,1,0,1);
   writeln(t);

 //  close(output);
end.

POJ 3278(BFS-搜索范围)

这题是BFS水的

主要是范围

0<=n,k<=100000  但是有可能搜到200000……

半天功夫才A.

program P3278;
const
   maxn=200000;
var
   n,k,i,j:longint;
   q,deep:array[1..maxn] of longint;
   b:array[0..maxn] of boolean;
procedure add(x:longint);
begin
   if not(b[x]) then
   begin
      b[x]:=true;
      inc(j);
      q[j]:=x;
      deep[j]:=deep[i]+1;
   end;
end;
begin
   read(n,k);
   i:=1;
   j:=1;
   fillchar(b,sizeof(b),false);
   b[n]:=true;
   q[1]:=n;deep[1]:=0;
   if n=k then
   begin
      writeln('0');
      halt;
   end;


   while i<=j do
   begin
      if (q[i]>0) then add(q[i]-1);
      if b[k] then break;
      if (q[i]<maxn) then add(q[i]+1);
      if b[k] then break;
      if (q[i]*2<maxn) then add(q[i]*2);
      if b[k] then break;
      inc(i);
   end;
   writeln(deep[j]);

end.

POJ 3256(SPFA)

这题只能对每一个点查一遍……

有向图的话能用floyd,可是迫于时限用了SPFA。

Program aa;
const
   maxk=10000;
   maxn=10000;
   maxm=10000;
var
   k,n,m,i,j,l:longint;
   a:array[1..maxk] of longint;
   q:array[1..maxn] of longint;
   edge,next,head:array[1..maxm] of longint;
   size:longint;
   res,num,b:array[1..maxn] of boolean;

procedure add(u,v:longint);
begin
   inc(size);
   edge[size]:=v;
   next[size]:=head[u];
   head[u]:=size;
end;


procedure spfa;
var
   i,j,p,now,v:longint;
begin
   i:=1;j:=1;
   while (i<=j) do
   begin
      now:=q[i];
      p:=head[now];
      while p<>0 do
      begin
         v:=edge[p];
         if not(b[v]) then
         begin
            b[v]:=true;
            inc(j);
            q[j]:=v;
         end;



         p:=next[p];
      end;
      inc(i);
   end;
   for i:=1 to n do
      res[i]:=res[i] and b[i];

end;

begin
   size:=0;
   fillchar(head,sizeof(head),0);
   fillchar(edge,sizeof(edge),0);
   fillchar(next,sizeof(next),0);
   fillchar(b,sizeof(b),false);
   fillchar(res,sizeof(res),true);
   fillchar(num,sizeof(num),false);
   read(k,n,m);
   for i:=1 to k do read(a[i]);
   for i:=1 to m do
   begin
      read(j,l);
      add(j,l);
   end;

   for i:=1 to k do
      if not(num[a[i]]) then
      begin
         num[a[i]]:=true;
         q[1]:=a[i];
         fillchar(b,sizeof(b),false);
         b[q[1]]:=true;
         spfa;
      end;
   l:=0;
   for i:=1 to n do if res[i] then inc(l);
   writeln(l);



end.