深搜题目总结

深度优先搜索(DFS)

让我们从刷题开始,掌握DFS

1. POJ-1258 Sum It Up

题面

给定指定的t和n个整数的列表,使用列表中加起来为t的数字查找所有不同的总和。例如,如果t = 4,n = 6,列表是[4,3,2,2,1,1],那么有四个不同的总和等于4:4,3 + 1,2 + 2,和2 + 1 + 1。(一个数字可以在一个总和中使用,就像它在列表中出现的次数一样,一个数字算作一个总和。)你的工作就是解决这个问题。

输入

输入将包含一个或多个测试用例,每行一个。每个测试用例包含t,total,后跟n,列表中的整数数,后跟n个整数x1,…,xn。如果n = 0,则表示输入结束;否则,t将是小于1000的正整数,n将是1到12之间的整数(包括),x1,…,xn将是小于100的正整数。所有数字将被恰好一个空格分隔。每个列表中的数字以非递增顺序显示,并且可能存在重复。

输出

对于每个测试用例,首先输出一行包含’Sums of’,total和冒号。然后输出每个总和,每行一个;如果没有总和,则输出’NONE’行。每笔金额中的数字必须以非递增顺序出现。数字可以在原始列表中重复多次重复。总和本身必须根据总和中出现的数字按递减顺序排序。换句话说,总和必须按其第一个数字排序;具有相同第一个数字的总和必须按其第二个数字排序;前两个数字相同的总和必须按第三个数字排序;等等。在每个测试用例中,所有总和必须是不相干的;相同的总和出现两次。

样本输入
4 6 4 3 2 2 1 1
5 3 2 1 1
400 12 50 50 50 50 50 50 25 25 25 25 25 25
0 0
样本输出
总和4:
4
3 + 1
2 + 2
2 + 1 + 1
总和5:
没有
总和400:
50 + 50 + 50 + 50 + 50 + 50 + 25 + 25 + 25 + 25
50 + 50 + 50 + 50 + 50 + 25 + 25 + 25 + 25 + 25 + 25

我觉得最重要的就是明白
1.题目考什么,分析思路
2.代码怎么写出来的
3.了解DFS过程

写代码过程

1.这道题就是考 DFS+去重

明白DFS和去重的代码思想

DFS过程

int s[15]    //存储每次搜索过程中的数,称它为 结果数组吧
int a[15]    //main函数中输入的数组
void dfs(int step,int sum, int d)  //step 结果数组下标,sum 数组和 ,d 输入的数组下标
{
	//判断边界
	if(){
		//当到达边界时的操作;
	}
	for(int i= ,i< ;i++){                        //尝试每一种可能
		dfs(step+1,sum+a[i],i+1);               //进行下一步
		  ………                    //去重;
	}
}

主要理解一下去重

while(i+1<n&&a[i]==a[i+1])
	i++;
i+1<n            :判断i不过界
a[i]==a[i+1]     :当从a[i]开始时,a[i]为第一位的所有情况已经找出,
                  因为经过sort排序,相同的数会排在一起,后面再出现相同的数为第一位,
                  会有相同的结果出现。所以要把跳过相同的数。

代码:

#include<iostream>
#include<algorithm>
using namespace std;
int t,n,total;
int s[15];
int book[15];
int a[15];
int c;
void dfs(int step,int sum,int d)
{
    if(sum>t||step==n)return;
    if(sum==t)  //判断边界
    {
        for(int j=0;j<step;j++)
        {
            cout<<sss[j];
            if(j!=step-1)cout<<"+";
        }
        cout<<endl;
        c=1;
        return;
    }
    for(int i=d;i<n;i++)
    {
            sss[step]=a[i];
            dfs(step+1,sum+a[i],i+1);
            while(i+1<n&&a[i]==a[i+1])
                i++;
    }
}
bool cmp(int a,int b)
{
    return a>b;
}
int main()
{
    cin>>t>>n;
    while(t!=0&&n!=0){
    for(int i=0;i<n;i++)
        cin>>a[i];
    sort(a,a+n,cmp);
    cout<<"Sums of "<<t<<":"<<endl;
    c=0;
    dfs(0,0,0);
    if(!c)cout<<"NONE"<<endl;
    cin>>t>>n;
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值