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 int using 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)); } }