• 【NOIP2015】子串(字符串DP)


    题意:有AB两个字符串,用A中连续的K串匹配B全串,问不同的方案总数

    n<=1000,m<=200,k<=m

    思路:设dp[k,i,j]为用k串 A中前i个字符匹配B中前j个字符的方案总数

             首先dp[k,i,j]=0 (a[i]<>b[j])

             然后就是考虑dp[k,i,j]能否从dp[k,i-1,j-1]即前一个连续转移来 dp[k,i,j]=dp[k,i,j]+dp[k,i-1,j-1]

             还有就是另起一串 dp[k,i,j]=dp[k-1,1,j-1]+dp[k-1,2,j-1]+...+dp[k-1,i-1,j-1]

             转移用前缀和优化,空间用滚动数组优化

           

    暴力

     1 const mo=1000000007;
     2 var dp:array[0..50,0..500,0..500]of longint;
     3     a,b:ansistring;
     4     n,m,k1,i,j,k,x,ans:longint;
     5 
     6 begin
     7  //assign(input,'1.in'); reset(input);
     8  //assign(output,'1.out'); rewrite(output);
     9  readln(n,m,k1);
    10  readln(a);
    11  readln(b);
    12  dp[0,0,0]:=1;
    13  for i:=1 to n do
    14   if a[i]=b[1] then dp[1,i,1]:=1;
    15  for i:=1 to k1 do
    16   for j:=1 to n do
    17    for k:=1 to m do
    18    begin
    19     if a[j]<>b[k] then continue;
    20     if a[j-1]<>b[k-1] then
    21      for x:=1 to j-1 do dp[i,j,k]:=(dp[i,j,k]+dp[i-1,x,k-1]) mod mo
    22       else
    23       begin
    24        for x:=1 to j-1 do dp[i,j,k]:=(dp[i,j,k]+dp[i-1,x,k-1]) mod mo;
    25        dp[i,j,k]:=(dp[i,j,k]+dp[i,j-1,k-1]) mod mo;
    26       end;
    27    end;
    28  for i:=1 to n do ans:=(ans+dp[k1,i,m]) mod mo;
    29  writeln(ans);
    30 // close(input);
    31 // close(output);
    32 end.

    加了优化

     1 const mo=1000000007;
     2 var dp,f:array[0..1,0..1000,0..200]of longint;
     3     a,b:ansistring;
     4     n,m,k1,i,v,j,k,ans:longint;
     5 
     6 begin
     7  //assign(input,'1.in'); reset(input);
     8  //assign(output,'1.out'); rewrite(output);
     9  readln(n,m,k1);
    10  readln(a);
    11  readln(b);
    12  dp[0,0,0]:=1;
    13  for i:=0 to n do f[0,i,0]:=1;
    14  for i:=1 to k1 do
    15  begin
    16   v:=1-v;
    17   fillchar(f[v],sizeof(f[v]),0);
    18   fillchar(dp[v],sizeof(dp[v]),0);
    19   for j:=1 to n do
    20    for k:=1 to m do
    21    begin
    22     if a[j]=b[k] then
    23     begin
    24      dp[v,j,k]:=f[1-v,j-1,k-1];
    25      if a[j-1]=b[k-1] then dp[v,j,k]:=(dp[v,j,k]+dp[v,j-1,k-1]) mod mo;
    26     end;
    27     f[v,j,k]:=(f[v,j-1,k]+dp[v,j,k]) mod mo;
    28    end;
    29  end;
    30  for i:=1 to n do ans:=(ans+dp[v,i,m]) mod mo;
    31  writeln(ans);
    32  //close(input);
    33  //close(output);
    34 end.
  • 相关阅读:
    WinCE NAND flash
    正确选择报表工具的十大标准
    从技术岗位走向管理岗位:机会是留给有准备的人
    创业失败的七个原因及解决之道
    技术人员如何参与产品设计讨论:激活那一潭死水
    基于Android Studio搭建hello world工程
    基于Android Studio搭建Android应用开发环境
    JS数组去重的6种算法实现
    八款前端开发人员更轻松的实用在线工具
    海市蜃楼-嘉兴外蒲岛奇遇
  • 原文地址:https://www.cnblogs.com/myx12345/p/5893926.html
Copyright © 2020-2023  润新知