社区讨论
P4124手机号码数位dp记忆化搜索70分
P4124[CQOI2016] 手机号码参与者 2已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @lo1bel6n
- 此快照首次捕获于
- 2023/10/22 18:17 2 年前
- 此快照最后确认于
- 2023/11/02 18:37 2 年前
CPP
#include <bits/stdc++.h>
#define ll long long
#define int long long
using namespace std;
ll a, b;
int dp[20][2][2][10][10];//长度 8 4 前 相同
int dig[20];
int cnt = 0;
int dfs(int len, bool _8, bool _4, int pre, int same, bool flag)//长度 8 4 前 相同个数 是否dig
{
if(!len) return !(_8&_4) && same==3;
if(!flag&&~dp[len][_8][_4][pre][same]) return dp[len][_8][_4][pre][same];
int up = flag?dig[len]:9;
int ret = 0;
for (int i=len==cnt;i<=up;++i)
{
if(!same) ret += dfs(len-1, _8||i==8, _4||i==4, i, 1, flag&&i==up);
else ret += dfs(len-1, _8||i==8, _4||i==4, i, (same==3?same:(i==pre?same+1:1)), flag&&i==up);
}
if(!flag) dp[len][_8][_4][pre][same] = ret;
return ret;
}
int solve(int x)
{
cnt=0;
while(x)
{
dig[++cnt] = x%10;
x/=10;
}
return dfs(cnt, 0, 0, 0, 0, 1);
}
signed main()
{
memset(dp, -1, sizeof(dp));
scanf("%lld%lld", &a, &b);
printf("%lld", solve(b) - solve(a-1));
return 0;
}
比较简短,所以没写什么注释
回复
共 4 条回复,欢迎继续交流。
正在加载回复...