zoukankan      html  css  js  c++  java
  • bzoj3530

    比较恶心的题目
    不难发现是在自动机上做数位dp
    注意要考虑前导0,题目中给出的233是幸运数,20233不是
    为此我非常猥琐的写了一个四维dp,用记忆化搜索实现

      1 const mo=1000000007;
      2 var dp:array[0..1,0..1,0..1205,0..1505] of longint;
      3     trie:array[0..2005,'0'..'9'] of longint;
      4     q,f:array[0..2005] of longint;
      5     can:array[0..2005] of boolean;
      6     ans,i,n,m,t,j,k,l:longint;
      7     s,ss:ansistring;
      8     ch:char;
      9 
     10 procedure ac;
     11   var h,r,i,x,y:longint;
     12       c:char;
     13   begin
     14     h:=1;
     15     r:=0;
     16     for c:='0' to '9' do
     17       if trie[0,c]>0 then
     18       begin
     19         inc(r);
     20         q[r]:=trie[0,c];
     21       end;
     22 
     23     while h<=r do
     24     begin
     25       x:=q[h];
     26       for c:='0' to '9' do
     27         if trie[x,c]>0 then
     28         begin
     29           y:=trie[x,c];
     30           inc(r);
     31           q[r]:=y;
     32           j:=f[x];
     33           while (j>0) and (trie[j,c]=0) do j:=f[j];
     34           f[y]:=trie[j,c];
     35           if can[trie[j,c]] then can[y]:=true; //注意
     36         end;
     37       inc(h);
     38     end;
     39   end;
     40 
     41 function calc(p,z,i,j:longint):longint; //p表示当前位置上的数是否需要小于N当前位上的数
     42                                         //z表示假如当前位出现0,是否是多余的0  
     43   var k,q,zz:longint;
     44       s,c,e:char;
     45   begin
     46     if can[j] then exit(0);
     47     if i=m then exit(1);
     48     if dp[p,z,i,j]<>-1 then exit(dp[p,z,i,j]);
     49     dp[p,z,i,j]:=0;
     50     if p=0 then e:=ss[i+1] else e:='9';
     51     for c:='0' to e do
     52     begin
     53       if (p=0) and (c=e) then q:=0
     54       else q:=1;
     55       k:=j;
     56       while k>-1 do
     57       begin
     58         if trie[k,c]>0 then break;
     59         k:=f[k];
     60       end;
     61       if k=-1 then k:=0 else k:=trie[k,c];
     62       if (z=0) and (c='0') then  //开头多余的0不考虑
     63       begin
     64         zz:=0;
     65         k:=0;  //多余的0不在自动机上匹配
     66       end
     67       else zz:=1;
     68       dp[p,z,i,j]:=(dp[p,z,i,j]+calc(q,zz,i+1,k)) mod mo;
     69     end;
     70     exit(dp[p,z,i,j]);
     71   end;
     72 
     73 begin
     74   read(ch);
     75   while ch='0' do read(ch);
     76   readln(ss);
     77   ss:=ch+ss;
     78   m:=length(ss);
     79   f[0]:=-1;
     80   readln(n);
     81   for i:=1 to n do
     82   begin
     83     readln(s);
     84     j:=0;
     85     l:=length(s);
     86     for k:=1 to l do
     87     begin
     88       if trie[j,s[k]]=0 then
     89       begin
     90         inc(t);
     91         trie[j,s[k]]:=t;
     92       end;
     93       j:=trie[j,s[k]];
     94     end;
     95     can[j]:=true;
     96   end;
     97   ac;
     98   fillchar(dp,sizeof(dp),255);
     99   ans:=(calc(0,0,0,0)-1+mo) mod mo;
    100   writeln(ans);
    101 end.
    View Code
  • 相关阅读:
    firefox安装教程
    shell脚本介绍
    vue 图片引入
    vscode 常用插件
    vscode 打不开chrome浏览器解决方案
    win10 wifi 密码查看
    爽文 主角如 石昊 白小纯 方行 秦牧 楚风
    codepen, jsrun 使用iframe嵌入
    uniapp 自定义扫一扫页面
    数组(遍历删除多个元素)
  • 原文地址:https://www.cnblogs.com/phile/p/4472996.html
Copyright © 2011-2022 走看看