HDU 2089 不要62 数位dp
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2089
不要62
Memory Limit: 32768/32768 K (Java/Others)
输入
输入的都是整数对n、m(0<n≤m<1000000),如果遇到都是0的整数对,则输入结束。
输出
对于每个整数对,输出一个不含有不吉利数字的统计个数,该数值占一行位置。
样例输入
1 100
0 0
样例输出
80
题解
简单数位dp
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;
const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-6;
const double PI = acos(-1.0);
//start----------------------------------------------------------------------
const int maxn=22;
int arr[maxn],tot;
LL dp[maxn][2];
///ismax标记表示前驱是否是边界值
LL dfs(int len,int is6, bool ismax) {
if (len == 0) {
///递归边界,这说明前驱都合法了
return 1LL;
}
if (!ismax&&dp[len][is6]>=0) return dp[len][is6];
LL res = 0;
int ed = ismax ? arr[len] : 9;
///这里插入递推公式
for (int i = 0; i <= ed; i++) {
if(i==4) continue;
if(i==2&&is6) continue;
else{
res += dfs(len - 1, i==6, ismax&&i == ed);
}
}
return ismax ? res : dp[len][is6] = res;
}
LL solve(LL x) {
tot = 0;
while (x) {
arr[++tot] = x % 10;
x /= 10;
}
return dfs(tot, false, true);
}
void init() {
clr(dp,-1);
}
int main() {
LL x,y;
init();
while(scf("%lld%lld",&x,&y)==2&&x){
prf("%lld\n",solve(y)-solve(x-1));
}
return 0;
}
//end-----------------------------------------------------------------------