165 Stamps(*****)推荐

/*
推荐题型:五星,题很不错,锻炼思维。想到了要进行两次递归搜索,一次选值,一次判断。但是选值时会出现问题,因为无法知道上届。所以遇到了瓶颈,看别人代码后,很不错。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;
}

你可能感兴趣的:(165 Stamps(*****)推荐)