您的位置:首页 > 其它

[BZOJ1026][SCOI2009]windy数 解题报告|数位dp

2015-04-13 11:12 453 查看

Description




  windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,在A和B之间,包括A和B,总共有多少个windy数?



  一直还是有点怕数位DP的...包括今天做这道简单的小题也花了很久的时间处理细节。

  首先大体的思路非常明显,定义一个DP f[i,j]表示第i位放数字j有多少种方法,可以通过前一位的一些满足的数字推出这一位。

  但是如何来解决在某个数A的范围内呢...?

  并且一旦前面的没有取满,这一位都是可以0..9任意取的

  并且还要考虑以这一位为开头的情况

  没有前导零,也就是说当这一位为0的时候是不能作为开头的。

  思考了一会儿,想出了一种方案。f[i,j]表示第i为放数字j并且从1~i并排除取到原数的方案数

  那么通过f[i-1]然后枚举0~9就可以先得出初步的f[i](因为i-1位以前都没有取到满了,这一位随便怎么取都不会超过原数

  第二部分就是当前数为起点,那么我们枚举1~9,inc(f[i][j])就可以了

  还有一种情况,就是i-1位已经取满了,当前这位只能取0~num[i]这些数(num[i]表示原数在第i位的数字)

  但是我们只能枚举到num[i]-1,因为要维护f[i]这个数组的性质:没有取到满

  注意细节:第三种情况能够转移当且仅当1~i-1位都满足windy数的性质 (这里我们可以用一个bool类型标记)

  处理完之后再判断1~i是否满足windy数的性质

  f[最后一位][0..9]就是答案。

  其实还没有结束...别忘了原数,如果那个bool类型到最后还是为真,说明原数也是一个windy数

  但是显然我们在f数组里是不会统计到原数的,这个时候还要答案+1

  最后还有一个细节,就是特判0的情况,虽然题目保证>=1但是我们要的答案是solve(r)-solve(l-1),还是会即算到0的情况

  要特判solve(0)=0

  前几天写惯了树剖今天几道小题真是爽啊...

  

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

program bzoj1026;
var i,l,r:longint;
w,num:array[-1..15]of longint;
f:array[-1..15,0..9]of longint;

function solve(p:longint):longint;
var i,j,k,ans:longint;
flag:boolean;
begin
if p=0 then exit(0);
fillchar(f,sizeof(f),0);
for i:=9 downto 1 do if p div w[i]>0 then break;
if p div w[i]>0 then inc(i);
for j:=i downto 1 do num[j]:=p div w[j-1] mod 10;
for j:=1 to num[i]-1 do f[i,j]:=1;
flag:=true;
for i:=i-1 downto 1 do
begin
for j:=0 to 9 do
for k:=0 to 9 do if abs(j-k)>=2 then inc(f[i,j],f[i+1,k]);
for j:=1 to 9 do inc(f[i,j]);
if flag then for j:=0 to num[i]-1 do if abs(j-num[i+1])>=2 then inc(f[i,j]);
if abs(num[i]-num[i+1])<2 then flag:=false;
end;
ans:=0;
for i:=0 to 9 do inc(ans,f[1,i]);
if flag then inc(ans);
exit(ans);
end;

begin
w[0]:=1;
for i:=1 to 9 do w[i]:=w[i-1]*10;
readln(l,r);
writeln(solve(r)-solve(l-1));
end.


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