码迷,mamicode.com
首页 > 其他好文 > 详细

回溯法第6题—0/1字符串问题

时间:2014-08-14 19:37:39      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   io   ar   问题   cti   div   

[问题描述]输入仅由0/1组成的长度为n的字符串,并且其中不可含有三个连续的相同子串。
输入:字符串的长度n(n<=40)。
输出:所有满足条件的字符串的个数
[样例输入]

2
[样例输出]

4
[问题分析]
设0/1序列的长度为L,x,y,z分别为第三、第二、第一个子串的首指针;
初始:x=L;y=L-1;z=L-2;
若三个数字不同,dec(x,1);dec(y,2);dec(z,3);
直到 (a[z]...a[y-1]=a[y]...a[x-1]=a[x]...a[l]) or (z<=0)
再开三个指针判断子串是否相等;
==============================分割线==============================
优化:利用对称性,比如n=6时,011001中不含3个连续的相同子串;那么100110也必然不含3个连续的相同子串;
因此只需查找第1位为0的序列,将得到的方案数乘以2即为所求。
字符串的生成方法:回溯法。
初始时a[1]=0,然后try(a[2]),顺序为先填0再填1,填0后满足条件则填下一位,否则改为1,若还是不满足条件,回溯至前一位,若满足条件,填下一位。
生成一个字符串时,方案数+2;

var a:array[1..40]of byte;//0/1序列
    tot:longint;
    L:integer;//位指针
    n:integer;
function judge(L:integer):boolean;
var x,y,z:integer;r,q,p:integer;
begin
  x:=L;y:=L-1;z:=L-2;//指针初始化
  while z>0 do
   begin
    p:=x;q:=y;r:=z;
    while (r<y)and(a[p]=a[q])and(a[q]=a[r]) do begin inc(p);inc(q);inc(r);end;//遍历子串
    if r=y then exit(false);//如果三个子串完全一样就返回false
    dec(x,1);dec(y,2);dec(z,3);
   end;
  exit(true);
end;
procedure search(L:integer);
begin
   if L>n then begin inc(tot,2); exit; end;
   a[L]:=0;
   if judge(L) then search(L+1);
   a[L]:=1;
   if judge(L) then search(L+1);
 end;
begin
  readln(n);
  a[1]:=0;
  L:=1;
  tot:=0;
  search(2);
  writeln(tot);
end.

回溯法第6题—0/1字符串问题,布布扣,bubuko.com

回溯法第6题—0/1字符串问题

标签:style   blog   color   io   ar   问题   cti   div   

原文地址:http://www.cnblogs.com/cuichen/p/3912875.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!