题解:CF331C3 The Great Julya Calendar
RainRecall · · 题解
有一个朴素的 dp 是直接设
进一步观察性质发现,dp 数组是递增的。
:::info[这个结论的简单说明]
设
也就是说转移方程变为了
数位 dp 通常从高到低考虑,每次考虑到一位时递归下一位的状态,完成转移并使得总状态数可以接受。我们按照这个方式来走的话,可以设
:::warning[细节问题]
转移到最后,我们可能会转移到
现在我们保证了做法的正确性,但是没有说明做法的复杂度是否合理。但是分析一下,从
-
读入的数的后缀。
-
一个个位数后面一堆
9 ,最后一个个位数。 -
一个个位数后面一堆
0 ,最后一个个位数。
第一种状态的量级为
实现的时候我们要用 map 对状态进行记录,可能会再填一个 log,但是采用哈希表就不会。这里还是实现前者。
#include<bits/stdc++.h>
#define int long long
#define pi pair<int,int>
using namespace std;
map<pi,pi>qwq;
int n;
pi dfs(int mx,int n){
if(qwq.count({mx,n}))return qwq[{mx,n}];
if(n<=9)return {n>0||mx>0,n-max(mx,n)};
int hd=1;
while(hd<=n/10)hd*=10;
pi low=dfs(max(mx,n/hd),n%hd);
pi hi=dfs(mx,n-n%hd+low.second);
return qwq[{mx,n}]={low.first+hi.first,hi.second};
}
signed main(){
cin>>n;
cout<<dfs(0,n).first;
return 0;
}