HDU 1258 Sum It Up

题目地址:点击打开链接

思路:好题,一步一步分析,把我错误的代码也贴上来,便于深入理解

错误代码1:

#include<stdio.h>
#include<string.h>
int t,visit[15],n,a[15];
void dfs(int l)
{

	int i,flag = 1;
	if(l > t)
		return;
	else if(l == t)
	{
		for(i=0; i<n; i++)
		{
			if(visit[i])
			{
				if(flag)
				{
					printf("%d",a[i]);
					flag = 0;
				}
				else
					printf("+%d",a[i]);
			}
		}
		printf("\n");
	}
	else
	{
		for(i=0; i<n; i++)
		{
			if(!visit[i])
			{
				visit[i] = 1;
				l += a[i];
				dfs(l);
				l -= a[i];
				visit[i] = 0;
			}
			//l -= a[i];
			//visit[i] = 0;要放在里面,别乱搞
		}
	}
}
int main()
{
	int i,sum;
	while(scanf("%d%d",&t,&n) != EOF)
	{
		memset(visit,0,sizeof(visit));
		sum = 0;
		for(i=0; i<n; i++)
		{
			scanf("%d",&a[i]);
			sum += a[i];
		}
		if(sum < t)
			printf("NONE\n");
		else
			dfs(0);
	}
	return 0;
}
HDU 1258 Sum It Up_第1张图片
直接回溯,有多次重复输出,原来是要判断递归的起点是否相同,不同才继续DFS否则会重复输出

错误代码2:

#include<stdio.h>
#include<string.h>
int t,visit[15],n,a[15];
void dfs(int l)
{

	int i,flag = 1,last = -1;
	if(l > t)
		return;
	else if(l == t)
	{
		for(i=0; i<n; i++)
		{
			if(visit[i])
			{
				if(flag)
				{
					printf("%d",a[i]);
					flag = 0;
				}
				else
					printf("+%d",a[i]);
			}
		}
		printf("\n");
	}
	else
	{
		for(i=0; i<n; i++)
		{
			if(!visit[i] && a[i] != last)
			{
				last = a[i];
				visit[i] = 1;
				l += a[i];
				dfs(l);
				l -= a[i];
				visit[i] = 0;
			}
			//l -= a[i];
			//visit[i] = 0;要放在里面,别乱搞
		}
	}
}
int main()
{
	int i,sum;
	while(scanf("%d%d",&t,&n) != EOF)
	{
		memset(visit,0,sizeof(visit));
		sum = 0;
		for(i=0; i<n; i++)
		{
			scanf("%d",&a[i]);
			sum += a[i];
		}
		if(sum < t)
			printf("NONE\n");
		else
			dfs(0);
	}
	return 0;
}

HDU 1258 Sum It Up_第2张图片

递归起点已经不同了啊,为啥还有重复输出呢?递归起点是1和递归起点是3的时候输出结果都是3+1,必须要保证下一次递归的起点比这次低,才不会有重复输出

AC代码:

#include<stdio.h>
#include<string.h>
int t,visit[15],n,a[15],flag2;
void dfs(int l,int start)//只能是起点以后的数搞,不然大的输出一次,小的输出一次,起点以后搞就能保证只输出一次
{

	int i,flag = 1,last = -1;
	if(l > t)
		return;
	else if(l == t)
	{
		flag2 = 1;
		for(i=0; i<n; i++)
		{
			if(visit[i])
			{
				if(flag)
				{
					printf("%d",a[i]);
					flag = 0;
				}
				else
					printf("+%d",a[i]);
			}
		}
		printf("\n");
	}
	else
	{
		for(i=start; i<n; i++)
		{
			if(!visit[i] && a[i] != last)
			{
				last = a[i];
				visit[i] = 1;
				l += a[i];
				dfs(l,i+1);
				l -= a[i];
				visit[i] = 0;
			}
		}
	}
}
int main()
{
	int i,sum;
	while(scanf("%d%d",&t,&n))
	{
		if(n == 0)//要注意结束条件啊
			break;
		flag2 = 0;
		memset(visit,0,sizeof(visit));
		sum = 0;
		for(i=0; i<n; i++)
		{
			scanf("%d",&a[i]);
			sum += a[i];
		}
		printf("Sums of %d:\n",t);
		dfs(0,0);
		if(flag2 == 0)
			printf("NONE\n");
	}
	return 0;
}



你可能感兴趣的:(HDU 1258 Sum It Up)