P2064 奇妙的汽车

先转换一下题意:

给定 \(S\) ,求一组 \(a+a\times b_1+a\times b_1\times b_2+ \cdots=S\) ,并且 \(2\le b_i \le 9\) ,求最少要多少个 \(b\) (当然最后要+1

我们先把 \(a\) 提出来: \(a\times (1+b_1+b_1\times b_2 + \cdots)=S\)

然后把 \(a\) 移向移过去 \(1+b_1+b_1\times b_2+b_1\times b_2 \times b_3+ \cdots=\frac Sa\)

这里要求 \(\frac Sa\) 是整数,所以枚举 \(S\) 的因子就可以得到 \(a\) ,这里要注意,\(a\ne S\),否则的话可以一天完成,不符合题意,这里枚举的时候也要注意不要忘了枚举 \(a=1\) 的情况

然后我们来看这个柿子:
\[ 1+b_1+b_1\times b_2+b_1\times b_2 \times b_3+ \cdots \]
提出 \(b_1\) (乘法分配律):
\[ 1+b_1\times (1+b_2+b_2 \times b_3+ \cdots \]
然后再提出 \(b_2\)
\[ 1+b_1\times (1+b_2\times (1+b_3+ \cdots \]
然后你会发现这个柿子大概是这么个结构:
\[ 1+b_1\times (1+b_2\times (1+b_3\times (1+b_4\times (1+b_5\times ( \]
那么我们就dfs搜出每个 \(\frac Sa\) 最少能用几个 \(b_i\) 算出,那就先减去1然后再枚举 \(b_1\) ,因为要求是整数,所以又可以枚举因子了,然后除以 \(b_1\) 进到下一层递归再 -1枚举 \(b_2\) ...(详见代码)

因为每个 \(b_i\) 至少是 2 ,所以 \(\frac Sa\) 每进入一层递归就会至少缩小到原来的一半,所以这个复杂度是 \(O(\log \frac Sa)\) 的,但是还有每层枚举的次数,所以还要乘上8

所以总时间复杂度就是 \(O(\sqrt S \times \log S\times 8)\)

代码:

// This code wrote by chtholly_micromaker(MicroMaker)
#include <bits/stdc++.h>
#define reg register
#define int long long
using namespace std;
const int inf=0x3f3f3f3f3f3f3f3f;
template <class t> inline void read(t &s)
{
    s=0;
    reg int f=1;
    reg char c=getchar();
    while(!isdigit(c))
    {
        if(c=='-')
            f=-1;
        c=getchar();
    }
    while(isdigit(c))
        s=(s<<3)+(s<<1)+(c^48),c=getchar();
    s*=f;
    return;
}
int n;
inline int dfs(int u)
{
    if(u<=0)
    {
        if(!u)
            return 0;
        return inf;
    }
    --u;
    reg int res=inf;
    for(int i=2;i<=9;++i)
        if(!(u%i))
            res=min(res,dfs(u/i)+1);
    return res;
}
signed main(void)
{
    cin>>n;
    reg int lim=sqrt(n);
    reg int ans=inf;
    for(int i=2;i<=lim;++i)
        if(!(n%i))
            ans=min(ans,dfs(i));
    ans=min(ans,dfs(n));
    if(ans==inf)
        puts("-1");
    else
        printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/chinesepikaync/p/12420790.html