九度 oj 题目1038:Sum of Factorials

来源:互联网 发布:js判断两个日期大小 编辑:程序博客网 时间:2024/06/08 13:35

http://ac.jobdu.com/problem.php?pid=1038

这道题首先想到用组合数,如果要列出完整的组合内容应考虑到用所有组合, 所有排列的模板。如果只是要组合的和(或者积)就相当于二叉搜索,中途还可以剪枝。


code1:

#include <stdio.h>static int f[11];static int n;void make_f(){     f[0] = 1;    for (int i = 1; i < 11 ; ++i) {         f[i] = i * f[i-1];     }  }  bool dfs(int x, int l){     if(x==n) return true;      if(l>10) return false;     if(x>n) return false;     bool b0 = dfs(x,l+1);     if(b0) return true;     x += f[l];    bool b1 = dfs(x,l+1);     return b1;} int main(){     make_f();     while(scanf("%d",&n) !=EOF){         if(n==0) printf("NO\n");           else printf("%s\n",dfs(0,0)?"YES":"NO");     }  }  


后来看题解发现,其实这是一道可以用贪心算法求解的题。因为f[i] > sum(f[0],,,,f[i-1])。 如果n是sum of factorials,且n>=f[i], 那么n中一定包含f[i],否则后面的所有f[0]...f[i-1]的和加起来都小于n。

 code2:

#include <stdio.h>static int f[11];void make_f(){     f[0] = 1;     for (int i = 1; i < 11; ++i) {         f[i] = i * f[i-1];     } }  int main(){     make_f();    int n;     while(scanf("%d",&n)!=EOF){         if(n==0){             printf("NO\n");              continue;        }         for (int i = 10; i >=0 ; --i) {             if (n>=f[i]) {                 n -= f[i];             }          }          printf("%s\n",n==0?"YES":"NO");      }  }  



0 0
原创粉丝点击