NYOJ 91 factorial sum

sum of factorials

Time Limit: 3000 ms | Memory Limit: 65535 KB
Difficulty: 3
describe

Give you a non-negative integer n, determine whether n is the sum of the factorials of some numbers (these numbers are not allowed to be reused and are positive numbers), such as 9=1! +2!+3!, if yes, output Yes, otherwise output No;

enter
The first line has an integer 0<m<100, indicating that there are m groups of test data;
each group of test data has a positive integer n<1000000;
output
If the condition is met, output Yes, otherwise output No;
sample input
2910
Sample output
Yes
No

Idea 1: Search

Pay attention to the understanding of this dfs: when each layer calls the next layer, the value of the calling layer is determined by the following two layers. According to the characteristics of dfs, if the next layer has the correct value of the upper calling layer, it is true (as an ordinary function Call the other two functions, return true if correct)

By analogy, when reaching the bottom of the search, if one of the bottom layers is correct, the total result is correct, that is, there are combinations that satisfy the factorial sum of n.

The complexity of this algorithm is very high O(2^n) two cases per layer, until the bottom layer makes a judgment.

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

int t,n;
int f[12];
int fac (int n) {
	if(n == 0 || n == 1)
		return 1;
	else return n*fac(n-1);
}
bool dfs(int p,int sum){
	if(p == 12){
		return sum == n;
	}
	if(dfs(p+1,sum+f[p]))
		return true;
	if(dfs(p+1,sum))
		return true;

	return false;
}
intmain()
	{
		for(int i = 1; i < 12; ++i){
			f[i] = fac(i);
		}
		scanf("%d",&t);
		while(t--){
			scanf("%d",&n);
			if(dfs(1,0)){
				printf("Yes\n");
			}
			else{
				printf("No\n");
			}	
		}
			
		return 0;	
	}

The second idea is greedy:

In fact, greed is not all right for such problems, it is only right in this case

For example, leaving this question aside, ask whether a given N is the sum of some of some numbers

9

1 3 6 7

At this time, according to this logic, it is judged as No, but in fact 3+6 = 9 is possible

I think the necessary condition for this approach to be correct is that the numbers are of different orders of magnitude (of course some are of the same order of magnitude, but that doesn't make the case above)

Rewrite it when you know the specific principle. . .

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

int t,n;
int f[12];
int fac (int n) {
	if(n == 0 || n == 1)
		return 1;
	else return n*fac(n-1);
}

intmain()
	{
		for(int i = 1; i < 12; ++i){
			f[i] = fac(i);
		}
		scanf("%d",&t);
		while(t--){
			scanf("%d",&n);
			for(int i = 9; i > 0; --i){//Start from the big number, and then subtract it if you can compare it in turn
				if(n >= f[i])
					n -= f[i];
			}
			if(n == 0){
				printf("Yes\n");
			}
			else{
				printf("No\n");
			}	
		}
			
		return 0;	
	}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324409205&siteId=291194637