hdu 2555 Bomb 数位dp

题意:求1-n内包含‘49’的数字有多少个。

分析:很裸的数位dp。用f[i,j,0]表示i位的数最高位为j且不包含49的数有多少个。f[i,j,1]表示包含49的有多少个。

f[i,j,0]=sum(f[i-1,l,0])。f[i,j,1]=sum(f[i-1,l,1]+f[i-1,l,0](j=4且l=9))。

代码:

var
  i,j,k,l,t:longint;
  n:int64;
  f:array[0..20,0..9,0..1] of int64;

function work(x:int64):int64;
var
  a1,i,j,t:longint;
  a:array[1..20] of longint;
begin
  a1:=0;
  while x>0 do
  begin
    inc(a1);
    a[a1]:=x mod 10;
    x:=x div 10;
  end;
  a[a1+1]:=0;
  work:=0;
  t:=0;
  for i:=a1 downto 1 do
  begin
    for j:=0 to a[i]-1 do
    begin
      work:=work+f[i,j,1];
      if t=1 then work:=work+f[i,j,0];
    end;
    if (a[i+1]=4)and(a[i]=9) then t:=1;
  end;
end;

begin
  f[0,0,0]:=1;
  for i:=1 to 19 do
    for j:=0 to 9 do
      for k:=0 to 1 do
        for l:=0 to 9 do
          if k=0
            then begin
                   if (j<>4)or(l<>9) then f[i,j,k]:=f[i,j,k]+f[i-1,l,k];
                 end
            else begin
                   f[i,j,k]:=f[i,j,k]+f[i-1,l,k];
                   if (j=4)and(l=9) then f[i,j,k]:=f[i,j,k]+f[i-1,l,0];
                 end;
  readln(t);
  for l:=1 to t do
  begin
    readln(n);
    writeln(work(n+1));
  end;
end.


你可能感兴趣的:(hdu 2555 Bomb 数位dp)