牛客-送分了QAQ——数位dp的运用题
Posted C+++++++++++++++++++
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客-送分了QAQ——数位dp的运用题相关的知识,希望对你有一定的参考价值。
题目
题目详解
- 数位dp问题,两步走:1.转数组。2.开始记忆化搜索。
记忆化搜索和当前位是否是限制状态,以及计数状态是否相同。
- state==0则表示到当前位置还未出现4/3/8。
- state==1则表示到当前位置的前一个位置已经出现3。
- state==2则表示到当前位置已经出现4或者连续的38。
解题代码
#include <bits/stdc++.h>
using namespace std;
//TODO 数位dp两步:一、把数字转数组。二、通过记忆化dfs计算(记忆化重点在:是否处于限制状态以及当前的计数状态)。
//TODO 三个状态:
// state==0则表示到当前位置还未出现4/3/8
// state==1则表示到当前位置的前一个位置已经出现3
// state==2则表示到当前位置已经出现4或者连续的38
int a[20];//用于转的数组
int memo[15][3];//用于记忆化的备忘录
int dp(bool limit, int pos, int state)
if (pos == 0)return state == 2;
if (!limit && memo[pos][state])return memo[pos][state];
int up = limit ? a[pos] : 9;
int ret = 0;
for (int i = 0; i <= up; ++i)
if (i == 4 || state == 2 || (i == 8 && state == 1))
ret += dp(limit && i == up, pos - 1, 2);
else if (i == 3)
ret += dp(limit && i == up, pos - 1, 1);
else
ret += dp(limit && i == up, pos - 1, 0);
if (!limit)memo[pos][state] = ret;
return ret;
int to_cal(int num)
int pos = 0;
while (num)
a[++pos] = num % 10;
num /= 10;
return dp(1, pos, 0);
int main()
ios::sync_with_stdio(false);
int c, d;
int l, r;
while (cin >> c >> d)
if (c == 0 && d == 0)
return 0;
l = to_cal(c - 1);
r = to_cal(d);
cout << r - l << '\\n';
return 0;
以上是关于牛客-送分了QAQ——数位dp的运用题的主要内容,如果未能解决你的问题,请参考以下文章