/* 推荐题型:五星,题很不错,锻炼思维。想到了要进行两次递归搜索,一次选值,一次判断。但是选值时会出现问题,因为无法知道上届。所以遇到了瓶颈,看别人代码后,很不错。dfs中的嵌套在两条if语句中,所以程序肯定会存在终止的情况。 题意:k种邮票,面值自定,共h张,求可组合成的最大值。要求从1开始连续。 */ #include <cstdio> #include <cstring> int h,k; int ans[15],res; bool check(int target,int dep,int num,int tot,int *A,int end) { if(target==tot)//看递归函数,要看主题,这里就是判断是否可以等于target return 1; if(dep==end || num==h) return 0; if(check(target,dep+1,num,tot,A,end))//这里的使用存在技巧,仔细体会。和下面那个if语句可以保证所有的组合都可以进行一次判断 return 1; if(check(target,dep,num+1,tot+A[dep],A,end)) return 1; return 0; } void dfs(int cur,int *A,int dep) { if(check(cur,0,0,0,A,dep)) dfs(cur+1,A,dep);//架空,不存储cur if(dep<k) { A[dep]=cur;//存储cur dfs(cur+1,A,dep+1); //A[dep]=-1; } if(cur-1>res) { res=cur-1; memcpy(ans,A,sizeof(ans)); } } int main() { //freopen("data.in","r",stdin); int A[15]; while(scanf("%d %d",&h,&k)==2 && h && k) { //memset(A,-1,sizeof(A)); res=0; dfs(1,A,0); for(int i=0;i<k;i++) printf("%3d",ans[i]); printf(" ->%3d\n",res); } return 0; }