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
  • 相关阅读:
    Hdu 1257 最少拦截系统
    Hdu 1404 Digital Deletions
    Hdu 1079 Calendar Game
    Hdu 1158 Employment Planning(DP)
    Hdu 1116 Play on Words
    Hdu 1258 Sum It Up
    Hdu 1175 连连看(DFS)
    Hdu 3635 Dragon Balls (并查集)
    Hdu 1829 A Bug's Life
    Hdu 1181 变形课
  • 原文地址:https://www.cnblogs.com/phile/p/4472996.html
Copyright © 2011-2022 走看看