[基础数位DP] HDU2089 不要62 HDU3555 Bomb

来源:互联网 发布:linux用yum安装rpm包 编辑:程序博客网 时间:2024/06/05 03:56

2个入门题。

HDU2089

题意: 求[L, R]范围内, 不含有数字4和62的数的个数。

记忆搜索的写法非常简单,已加入模板。

#include<bits/stdc++.h>using namespace std;int dp[15][2];int num[15];int dfs(int pos, int st, int f){ // st值 0表示不含4且不以6结尾 1表示不含4且以6结尾 2表示含有了4或者62,转移时其实直接舍去了,无需关注    if(pos < 1) return 1; // 到0就返回啦 表示所有位都填上了一个数 并且是合法的    if(!f && dp[pos][st] != -1) return dp[pos][st]; //如果已经搜过了就不用再搜了    int end = f? num[pos] : 9;    int ans = 0;    for(int i = 0; i <= end; ++i){        if(i == 4 || (st == 1 && i == 2)) continue; //当已出现4或者62的时候就不用搜了,搜了也肯定舍去        else if(i == 6) ans += dfs(pos-1, 1, f && i == end);        else ans += dfs(pos-1, 0, f && i == end);    }    if(!f) dp[pos][st] = ans; // 记忆化    return ans;}int solve(int n){ //返回 [0, n]区间内不含4和62的个数    int len = 0;    while(n){        num[++len] = n%10; // 位置0并没有定义        n /= 10;    }    return dfs(len, 0, 1);}int main(){    int n, m;    memset(dp, -1, sizeof(dp)); //此题是不需要重复初始化的    while(scanf("%d%d", &n, &m), n||m){        printf("%d\n", solve(m)-solve(n-1)); //要注意n-1会不会为负    }}

HDU3555

题意:求[0, N]范围内,含49的数的个数,和上面类似。

#include<bits/stdc++.h>#define ll long long intusing namespace std;ll dp[25][3];int num[25];ll dfs(int pos, int st, int f){ // st值 0表示不含49且不以4结尾 1表示不含49且以4结尾 2表示含有49    if(pos < 1) return st == 2; // 这题求含有49的,那就返回状态2    if(!f && dp[pos][st] != -1) return dp[pos][st];    int end = f? num[pos] : 9;    ll ans = 0;    for(int i = 0; i <= end; ++i){        if(st == 2 || (st == 1 && i == 9)) ans += dfs(pos-1, 2, f && i == end);        else if(i == 4) ans += dfs(pos-1, 1, f && i == end);        else ans += dfs(pos-1, 0, f && i == end);    }    if(!f) dp[pos][st] = ans;    return ans;}ll solve(ll n){    int len = 0;    while(n){        num[++len] = n%10;        n /= 10;    }    return dfs(len, 0, 1);}int main(){    int T;    memset(dp, -1, sizeof(dp));    scanf("%d", &T);    while(T--){        ll n;        scanf("%lld", &n);        printf("%lld\n", solve(n));    }}

0 0
原创粉丝点击