题意:求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.