您的位置:首页 > 其它

bzoj 1026 DP,数位统计

2013-11-20 14:39 399 查看
2013-11-20 08:11

原题传送门http://www.lydsy.com/JudgeOnline/problem.php?id=1026

首先我们用w[i,j]表示最高位是第i位,且是j的windy数个数

那么我们可以写出转移

w[i,j]:=w[i-1,k] abs(k-j)>=2

首先对于询问的a,b区间,我们可以转化成求1-a的个数,1-b的个数,然后差就行了

那么我们要求的就是1-x之间的windy数

假设x一共有len位,那么我们求len-1位以下的windy数可以直接用w算出来,直接

累加w[i,j]就行了

那么我们对于len位的数,只需要改变枚举的上界就好了,相当于固定第i位,求第i+1位的

情况,然后特判下如果abs(c[i]-c[i+1])<2(c[i]为x的第i位)直接退出就行了

/**************************************************************
Problem: 1026
User: BLADEVIL
Language: Pascal
Result: Accepted
Time:0 ms
Memory:228 kb
****************************************************************/

//By BLADEVIL
var
w                   :array[0..10,-1..10] of longint;
c                   :array[0..10] of longint;
a, b                :longint;

function ask(x:longint):longint;
var
len, Sum, i, j      :longint;

begin
if x=0 then exit(0);
len:=0;
while x>0 do
begin
inc(len);
c[len]:=x mod 10;
x:=x div 10;
end;
ask:=0;
for i:=1 to len-1 do
for j:=1 to 9 do
ask:=ask+w[i,j];

for j:=1 to c[len]-1 do
ask:=ask+w[len,j];

for i:=len-1 downto 1 do
begin
for j:=0 to c[i]-1 do
if abs(c[i+1]-j)>=2 then ask:=ask+w[i,j];
if abs(c[i+1]-c[i])<2 then break;
end;
end;

procedure main;
var
i, j, k             :longint;

begin
for i:=0 to 9 do w[1,i]:=1;
for i:=2 to 10 do
for j:=0 to 9 do
for k:=0 to 9 do
if abs(j-k)>=2 then w[i,j]:=w[i,j]+w[i-1,k];
readln(a,b);
writeln(ask(b+1)-ask(a));
end;

begin
main;
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: