标签:mic 出现 const -- style etc margin targe problem
类型:数位DP
传送门:>Here<
题意:求区间$[1, N]$中出现‘49‘的数量
解题思路
先上来乱DP了一通过了样例,但是老是WA。不太确定我处理重复的部分是否正确——题目要求多个49只能算一次,按照我原来的做法要特判减去多余的,但是这样啰嗦而且又不靠谱……
其实只需要反过来思考——区间$[1,N]$中出现‘49‘的数量等同于$N$减去区间$[1,N]$中没有‘49‘的数量。这就完全等同于早上的那道不要62了。非常巧妙
不过还是被坑调试了一小时——$digit[len+1] = 0$!!!!!
Code
本题还有一个坑点就在于边界条件的处理——题目要求的是$[1, N]$,而普通数位DP跑出来的却是包括0的。因此我们的cul(N)其实表示是$[0, N-1]$中不含‘49‘的数量。因此答案应该是$N - (cul(N+1)-1)$
/*By DennyQi 2018.8.13*/ #include <cstdio> #include <queue> #include <cstring> #include <algorithm> #define r read() #define Max(a,b) (((a)>(b)) ? (a) : (b)) #define Min(a,b) (((a)<(b)) ? (a) : (b)) using namespace std; typedef long long ll; #define int long long const int MAXN = 10010; const int MAXM = 27010; const int INF = 1061109567; inline int read(){ int x = 0; int w = 1; register int c = getchar(); while(c ^ ‘-‘ && (c < ‘0‘ || c > ‘9‘)) c = getchar(); if(c == ‘-‘) w = -1, c = getchar(); while(c >= ‘0‘ && c <= ‘9‘) x = (x << 3) + (x << 1) + c - ‘0‘, c = getchar(); return x * w; } int T,N; int dp[23][12],digit[23],pw[23]; inline void Init(){ for(int i = 0; i <= 9; ++i) dp[1][i] = 1; for(int i = 2; i <= 21; ++i){ for(int j = 0; j <= 9; ++j){ for(int k = 0; k <= 9; ++k){ if(j == 4 && k == 9) continue; dp[i][j] += dp[i-1][k]; } } } } inline int cul(int x){ int y = x, res = 0, len = 0; while(y > 0){ digit[++len] = y % 10; y /= 10; } digit[len+1]=0; for(int i = len; i; --i){ for(int j = 0; j < digit[i]; ++j){ if(digit[i+1] == 4 && j == 9) continue; res += dp[i][j]; } if(digit[i+1] == 4 && digit[i] == 9) break; } return res; } #undef int int main(){ #define int long long Init(); T = r; while(T--){ N = r; printf("%lld\n", N-(cul(N+1)-1)); } return 0; }
标签:mic 出现 const -- style etc margin targe problem
原文地址:https://www.cnblogs.com/qixingzhi/p/9469582.html