1026 windy数
数位dp,首先预处理出数组dp[i][j]表示首位为i的包含首位总位数为j的满足条件的数的个数,sum[i]表示位数为i的所有满足条件的数的个数,work(x)表示[1,x]中满足条件的数的个数,然后按套路dp下即可
/**************************************************************
Problem: 1026
User: syh0313
Language: C++
Result: Accepted
Time:4 ms
Memory:1292 kb
****************************************************************/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
using
namespace
std;
long
long
xx,yy,sum[20],dp[20][20];
int
a[20],topt,c[20];
void
init()
{
for
(
int
i=0;i<=9;i++) dp[i][1]=1;
for
(
int
j=2;j<=10;j++)
for
(
int
i=0;i<=9;i++)
{
for
(
int
k=0;k<=i-2;k++) dp[i][j]+=dp[k][j-1];
for
(
int
k=i+2;k<=9;k++) dp[i][j]+=dp[k][j-1];
}
for
(
int
j=1;j<=10;j++)
{
sum[j]=sum[j-1];
for
(
int
i=1;i<=9;i++) sum[j]+=dp[i][j];
}
}
long
long
dfs(
int
lc,
int
num)
{
long
long
ss=0;
if
(lc==topt+1)
return
1ll;
for
(
int
i=0;i<=num-2;i++)
if
(i<a[lc]) ss+=dp[i][topt-lc+1];
else
if
(i==a[lc]) {ss+=dfs(lc+1,i);
return
ss;}
for
(
int
i=num+2;i<=9;i++)
if
(i<a[lc]) ss+=dp[i][topt-lc+1];
else
if
(i==a[lc]) {ss+=dfs(lc+1,i);
return
ss;}
return
ss;
}
long
long
work(
int
x)
{
memset
(a,0,
sizeof
0);
memset
(c,0,
sizeof
c); topt=0;
if
(x==0)
return
0;
while
(x) {c[++topt]=x%10; x/=10;}
for
(
int
i=1;i<=topt;i++) a[i]=c[topt-i+1];
long
long
now=sum[topt-1];
for
(
int
i=1;i<a[1];i++) now+=dp[i][topt];
now+=dfs(2,a[1]);
return
now;
}
int
main()
{
init();
//for (int i=1;i<=10;i++) printf("%lld\n",sum[i]);
while
(~
scanf
(
"%lld%lld"
,&xx,&yy))
{
printf
(
"%lld"
,work(yy)-work(xx-1));
}
return
0;
}