[agc011E]Increasing Numbers-[思考题]
Description
Solution
依题得所有不下降数(设为a)可以拆为若干个全1数的和(如:1558=1111+111+111+111+111+1+1+1)
并且任意a所能拆出的全一数的个数<=9。则我们设定a拆出9个全1数,其中允许有0的存在。(以下的a[i]可以为所有自然数)
(任一全1数可以表示为$\frac{(10^{c}-1)}{9}$)
则$n=\sum _{i=1}^{9k}\frac{(10^{a[i]}-1)}{9}$
$9n=\sum _{i=1}^{9k}(10^{a[i]}-1)$
$9n+9k=\sum _{i=1}^{9k}10^{a[i]}$
由此可得,9n+9k这个数的每一位的和要<=9k。
我们要求最优的k。则针对数n,每次减掉一个不下降数,位数就会少1。
证明:假如在最优解中,要减x(x>1)个"不下降数"n的位数才会少1,这x个“不下降数”可以直接合并为1个“不下降数”,所以该解不是最优的,矛盾。
所以我们的k只要从1到n的位数枚举就可以了。进位的话直接暴力。(反正也进不了多少位)
Code
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; char s[500010];int n,num[500010],c,k; int pls(int &k) { int re=0; for (int i=1;i<=k;i++) { if (num[i]<10) break; re++; num[i+1]+=num[i]/10;num[i]%=10; } if (num[k+1]) k++; return re; } int _n; int main() { scanf("%s",s+1);n=_n=strlen(s+1); for (int i=1;i<=n;i++) num[i]=s[n-i+1]-'0',num[i]*=9; for (int i=1;i<=_n;i++) {num[i+1]+=num[i]/10;num[i]%=10;c+=num[i];} if (num[_n+1]) _n++,c+=num[_n]; for (int i=1;i<=n;i++) { k++; num[1]+=9;c+=9;c-=9*pls(_n); if (c<=9*k) { printf("%d",k);return 0; } } }