这一题要注意两点1、0!=1
2、最后是一个负数,并不一定是-1
可以使用dfs来做也可以当做背包来做。
//11352654 c00h00g 1775 Accepted 384K 500MS G++ 635B 2013-03-15 17:31:41
//不是很会写递归,参考别人的程序
#include<stdio.h>
#include<string.h>
int fib[10]={1,1,2,6,24,120,720,5040,40320,362880};
int n;
int vis[10];
int dfs(int i,int data){
if(data==n) return 1;
if(data>n) return 0;
for(int j=i;j<10;j++){
if(!vis[j]){
vis[j]=1;
if(dfs(j+1,data+fib[j])) return 1;// 一直返回到结束,这一句很关键
vis[j]=0;
}
}
return 0;
}
int main(){
while(scanf("%d",&n)&&n>=0){
if(n==0) { printf("NO\n");continue;}
memset(vis,0,sizeof(vis));
if(dfs(0,0)) printf("YES\n");
else printf("NO\n");
}
return 0;
}
dp程序,01背包刚好装满的情况
//11352748 c00h00g 1775 Accepted 4296K 110MS G++ 664B 2013-03-15 18:06:48
//dp解法,对应背包正好装满的情形
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define INF 0x7fffffff
int fib[10]={1,1,2,6,24,120,720,5040,40320,362880};
int n;
int dp[1000005];
int main(){
for(int i=1;i<1000005;i++)
dp[i]=-INF;
dp[0]=0;
for(int i=0;i<10;i++)//每个物品
for(int V=1000004;V>=0;V--){
if(V-fib[i]>=0&&dp[V-fib[i]]!=-INF)
dp[V]=max(dp[V],dp[V-fib[i]]+fib[i]);
}
while(scanf("%d",&n)&&n>=0){
if(n==0) { printf("NO\n");continue;}
//恰好装满的情况
if(dp[n]>0) printf("YES\n");
else printf("NO\n");
}
return 0;
}