给你一个非负数整数n,判断n是不是一些数(这些数不允许重复使用,且为正数)的阶乘之和,如9=1!+2!+3!,如果是,则输出Yes,否则输出No;
2 9 10
Yes No
方法1:贪心
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int fact[12];
void solve()
{
int n;
scanf("%d",&n);
for(int i=10;i>=1;i--)
if(n>=fact[i]) n-=fact[i];
if(n==0) printf("Yes\n");
else printf("No\n");
}
int main()
{
fact[1]=1;
for(int i=2;i<=10;++i)
fact[i]=fact[i-1]*i;
int m;
scanf("%d",&m);
while(m--) solve();
}
//贪心策略:每次从10!往下,若n>=fact[i],n-=fact[i]
//x!>(x-1)!+(x-2)!+(x-3)!+...(1)!
方法2:10!已经超过n的最大值
那么只要枚举1!,2!,3!。。。。。10!中任意几个数的和,即枚举1~10的子集
可以用二进制法:
//二进制法枚举子集
void get_sub(int n,int s)
{
for(int i=0;i<n;++i)
if(s&(1<<i)) ans+=fact[i];
}
for(int i=0;i<(1<<n);i++)
get_sub(n,i);
原文:http://www.cnblogs.com/orchidzjl/p/4371283.html