poj 1564 Sum It Up -- DFS 递归

题意:给一个数 t ,以及 n 个数,求 n 个数中的几个数加起来的和为 t 的情况有多少种。

注意:题目要求相同的组合方式不能出现2次,即 “3 4 1 1 1 1 ” 的结果为:“1+1+1”。

思路:一个  for  循环遍历一遍,每个 i 表示以当前数为起点开始一次DFS递归,当所遍历的和为 t 时,输出该组合方式,如果大于 t 则返回,小于则往下递归。以二维数组保存已经输出过的数据,当又一次需要输出数据时,则需确认二维数组里没有改组数据(个人觉得还有更好的方法)。

#include<stdio.h>
#include<string.h>
int n,m,i,j,k,t,l;
int data[20],vis[20],res[20],rear,flag,judge,save[20][20],num,count;// res数组保存当前的进行遍历的数据,save 数组则保存已经输出过的数据
int dir[11]={1,2,3,4,5,6,7,8,9,10,11};
void dfs(int x,int sum)
{
	if(sum>t) {return;}
   if(sum==t)
   {
	   flag=0;
	   for(l=0;l<num;l++)
	   {
		   count=0;
		   for(j=0;j<rear;j++)
			   if(save[l][j] == res[j]) count++; 
			   if(count==rear) {flag=1;break;}
	   }
	   if(!flag)
	   {
         for(j=0;j<rear;j++)
			 save[num][j]=res[j];
		 num++;
		 for(j=0;j<(rear-1);j++)
           printf("%d+",res[j]);
         printf("%d\n",res[rear-1]); 
	     judge=1;            // judge 为 1 表示输出过数据,为 0 则表示没输出过,则输出 “NONE” 
	   }
	   return;
   }
   for(k=0;k<n;k++) 
   {
	    x=x+1;
	    if(x>=n) return;  // 此处很关键!!!没加就WA,表示费解。
	   if(x<n&&vis[x]==0)
	   {
         vis[x]=1;
	     res[rear++]=data[x];
	     dfs(x,sum+data[x]);
		 rear--; // rear 表示 res 数组的长度,当递归返回时(已经输出过一组数据,或者 和 大于 t ),需要减 1 。
	     vis[x]=0;
	   }
   }
}
int main()
{
  while(scanf("%d%d",&t,&n)!=EOF && n!=0)
  {
    for(i=0;i<n;i++)
		scanf("%d",&data[i]);
	printf("Sums of %d:\n",t);
	judge=0;num=0;
	memset(save,0,sizeof(save));
	for(i=0;i<n;i++)    // for 循环遍历一遍
	{
		memset(vis,0,sizeof(vis)); // 每一个 i 都是一个新的开始,vis 及 res 数组需要初始化
		memset(res,-1,sizeof(res));
		vis[i]=1;
		rear=0;
		res[rear++]=data[i];
		dfs(i,data[i]);
		vis[i]=0;
	}
	if(!judge) printf("NONE\n");
  }
  return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值