POJ 1775 Sum of Factorials (ZOJ 2358)

http://poj.org/problem?id=1775

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1334

题目大意:

给一个数n看看n是否能够拆成几个阶乘的和

如9=1!+2!+3!


方法一:

最初想法是直接打出0~10的阶乘,10的阶乘已经大于n的范围

然后DFS,也过了。不过时间好惨。。。

注意n=0输出NO和0!=1

#include<cstdio>
#include<cstring>
const int MAXN=10;
int temp[12]={1,1};
bool used[12];
bool ok;
void dfs(int cur,int sum,int target)
{
	if(sum >target)
		return;

	if(sum==target)
	{
		ok=true;
		return ;
	}

	for(int i=cur;i<=MAXN;i++)
	{
		if(used[i]==false)
		{
			used[i]=true;
			dfs(i,sum+temp[i],target);		
			used[i]=false;
		}
	}
}
int main()
{
	
	for(int i=2;i<=MAXN;i++)
		temp[i]=temp[i-1]*i;

	int n;
	while(scanf("%d",&n),n>=0)
	{

		if(n==0)
		{
			printf("NO\n");
			continue;
		}
		memset(used,0,sizeof(used));
		ok=false;
		dfs(0,0,n);

		if(ok)  
            printf("YES\n");  
        else  
            printf("NO\n");  
	}
	return 0;
}


方法二:

贪心。。

然后把不超过n的阶乘减去。

因为n! >= sum(1 ! + 2!+……n-1!)

#include<cstdio>
const int MAXN=10;
int main()
{
	int temp[12]={1,1};
	for(int i=2;i<=MAXN;i++)
		temp[i]=temp[i-1]*i;

	int n;
	while(scanf("%d",&n),n>=0)
	{
		if(n==0)
		{
			printf("NO\n");
			continue;
		}
		for(int i=MAXN;i>=0;i--)
		{
			if(n >=temp[i])
				n-=temp[i];
		}
		if(n==0)
			printf("YES\n");
		else
			printf("NO\n");
	}
	return 0;
}



posted @ 2013-12-13 14:33  hr_whisper  阅读(196)  评论(0编辑  收藏  举报