[LOJ3186] 玩具

Description

玩具有很多不同的种类,每种玩具有很多歌,相同种类的两个玩具是无法区分的。

我们现在想知道总共有几个玩具。我们已知,如果在所有玩具中选择一些不同的玩具,可以玩 (n) 天,即任意两天选择的玩具中都存在任意一种玩具的数量不同,注意选择空集也是允许的。

输入仅包含一个正整数 (n)

Solution

如果各种物品的数量分别为 (c_1,c_2,...,c_k),那么可以选择的方案数显然是在每种物品中选择一个个数,即 ((c_1+1)(c_2+1)...(c_k+1))。现在问题是反过来的,给定了方案数,因此我们考虑对这个数字作分解即可。

考虑对于 (n) 的所有的拆分,假设有一种拆分为 (a_1 cdot a_2 cdot ... cdot a_k),那么很显然 (a_1-1,a_2-1,...,a_k-1) 可以是答案之一,我们计算出这种方案的数目,然后扔进 set 里,最后统计一下即可。

比较有趣的是这个过程的复杂度……

#include <bits/stdc++.h>
using namespace std;

#define int long long 
const int N = 1000005;


int n;
set <int> st;

void solve(int n,int last,int sum)
{
    for(int i=sqrt(n);i>=last;--i)
    {
        if(n%i==0)
        {
            solve(n/i,i,sum+i-1);
        }
    }
    st.insert(sum+n-1);
}

signed main()
{
    cin>>n;
    solve(n,2,0);
    cout<<st.size()<<endl;
    for(int i:st) 
    {
        cout<<i<<" ";
    }
}
原文地址:https://www.cnblogs.com/mollnn/p/13744067.html