您的位置:首页 > 其它

BZOJ1026 [SCOI2009] windy数

2016-07-12 10:39 274 查看
Description

  windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,

在A和B之间,包括A和B,总共有多少个windy数?

Input

  包含两个整数,A B。

Output

  一个整数

还算是一道标准的数位dp,不过使用递归完成数位dp的注意了,因为在同为零的情况下,数字零会有首位与非首位的区别,为了这个wa点本弱debug了一个多小时。

还有就是本弱犯的第二个错误,把首位的零直接当作-2处理,其实倒没啥,问题在于,dp[len][-2]是什么鬼东西嘛....

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
typedef long long ll;
ll num[100];
ll dp[100][10][10];
int lenx;
ll dfs(int len,ll digit,ll flag,bool first)
{
if(!len) return 1;
if(!flag&&dp[len][first][digit]!=-1) return dp[len][first][digit];
ll maxn=flag?num[len]:9;
ll ans=0;
for(int i=0;i<=maxn;i++)
{
if(i==0&&first) ans+=dfs(len-1,0,flag&&i==maxn,1);
else if(first) ans+=dfs(len-1,i,flag&&i==maxn,0);
else if(abs(i-digit)>=2)
{
ans+=dfs(len-1,i,flag&&i==maxn,0);
}
}
if(!flag) dp[len][first][digit]=ans;
return ans;
}
ll calc(ll x)
{
lenx=0;
while(x)
{
num[++lenx]=x%10;
x/=10;
}
return dfs(lenx,0,1,1);
}
int main()
{
int m,n;
memset(dp,-1,sizeof(dp));
scanf("%lld %lld",&n,&m);
//for(int i=0;i<20;i++)
//printf("%lld %lld\n",calc(m),calc(n-1));
//printf("%lld %lld\n",calc(m),calc(n-1));
printf("%lld\n",calc(m)-calc(n-1));
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm dp