HDOJ(HDU).1258 Sum It Up (DFS)
HDOJ(HDU).1258 Sum It Up (DFS) [从零开始DFS(6)]
从零开始DFS
HDOJ.1342 Lotto [从零开始DFS(0)] — DFS思想与框架/双重DFS
HDOJ.1010 Tempter of the Bone [从零开始DFS(1)] —DFS四向搜索/奇偶剪枝
HDOJ(HDU).1015 Safecracker [从零开始DFS(2)] —DFS四向搜索变种
HDOJ(HDU).1016 Prime Ring Problem (DFS) [从零开始DFS(3)] —小结:做DFS题目的关注点
HDOJ(HDU).1035 Robot Motion [从零开始DFS(4)]—DFS题目练习
HDOJ(HDU).1241 Oil Deposits(DFS) [从零开始DFS(5)] —DFS八向搜索/双重for循环遍历
HDOJ(HDU).1258 Sum It Up (DFS) [从零开始DFS(6)] —DFS双重搜索/去重技巧
HDOJ(HDU).1045 Fire Net [从零开始DFS(7)]—DFS练习/check函数的思想
题意分析
每组数据给出要凑出的目标数字num和数字个数n,然后依次给出n个数字。要求从n个数字中选出若干个数字,是的数字之和为nun。重复的组合只输出一次。
和之前做过的选数字的题目类似,也可以采用DFS的思想来做。这道题与HDOJ.1342 Lotto [从零开始DFS(0)]及其的相似:每个数字有2种选择,选/不选,只要我选择的这些数字的和为num就行了。但是不难想到会有重复的组合出现,例如给出的样例3:
400 12 50 50 50 50 50 50 25 25 25 25 25 25
要求从12个数字中选择出若干数字使得总和为400,我们可以发现选择6个50和4个25即可。那么若按照HDOJ.1342的思想,选/不选,问题就会出现:要从6个25中选4个25,会有C(6,4)中情况,也就是说最后的结果会多出11组相同的解。这显然不符合题意。
问题的关键在于如何去重,最先想到也是最容易想到的就是把每组解保存下来,如果遇到重复的只输出一组即可。很明显这种方法实现起来耗费的工程量是巨大的,非常麻烦。回到DFS的核心:递归。我们对于递归做出一些约束,当满足一定条件时,下面搜索的解会造成重复,就终止递归。这样得到的解,均是非重复的。关键就是找到这样的条件,或者说为递归创造这样的条件。
上代码。
代码总览
/*
Title:HDOJ.1258
Author:pengwill
Date:2017-2-8
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int num,n,pos;
int a[15],b[15];
bool judge = false;
void output(int depth)
{
for(int i =0 ;i< depth; ++i)
if(!i) printf("%d",b[i]);
else printf("+%d",b[i]);
printf("\n");
}
void dfs(int depth,int sum,int pos)
{
if(sum == num) {judge = true;output(depth); return;}
if(sum>num) return;// 超出了 终止递归
if(pos>=n) return; //选择的数的位置超出数据范围
b[depth] = a[pos];
dfs(depth+1,sum+a[pos],pos+1);
while(pos+1<n&&a[pos] == a[pos+1]) pos++;//关键
dfs(depth,sum,pos+1);
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d%d",&num,&n) && num){
printf("Sums of %d:\n",num);
for(int i = 0; i<n; ++i) scanf("%d",&a[i]);
judge = false;
dfs(0,0,0);
//output
if(judge == false) printf("NONE\n");
}
return 0;
}
还是按照HDOJ.1342 Lotto [从零开始DFS(0)]中写到的双重DFS的办法(即选/不选的思想),解决此题。
递归边界:当数字的和为num时,或者和超出了num,或者要选择的数字位置超出了n,终止搜索。
关键是下面这几句。
dfs(depth+1,sum+a[pos],pos+1);
while(pos+1<n&&a[pos] == a[pos+1]) pos++;//关键
dfs(depth,sum,pos+1);
首先是默认选择了pos这个位置的数字然后进行dfs。下面一个while循环表示如果下一个待选数字和本位置的待选数字一样的话,就跳过,一直跳到下一个待选数字不同的位置。如样例3:
400 12 50 50 50 50 50 50 25 25 25 25 25 25
就会从第一个50一直跳到最后一个50(下一个数字是25)。貌似看起来得不到正确结果,当然在第一层dfs不选择50的情况是没有正确解的。不放我们看一下下一层dfs,即选择了第一个50后的dfs。
进入第二层dfs依旧会有2种选择,要么选择第二个50,要么后续的50一个都不选。当然这时候一个50都不选的情况也是没有正确解的,继续看第三层。
进入第三层dfs还是会有2种选择,要么选择第三个50,要么后续的50一个都不选。但让后续50一个都不选的情况也没有正确解。
…………
依次类推,不难发现,这条while语句的作用就是:营造单一的选1个50,选2个50,选3个50这样的情况,从而避免了重复解的出现。
HDOJ(HDU).1258 Sum It Up (DFS)的更多相关文章
- (step4.3.4)hdu 1258(Sum It Up——DFS)
题目大意:输入t,n,接下来有n个数组成的一个序列.输出总和为t的子序列 解题思路:DFS 代码如下(有详细的注释): #include <iostream> #include <a ...
- HDU 1258 Sum It Up(DFS)
题目链接 Problem Description Given a specified total t and a list of n integers, find all distinct sums ...
- HDOJ(HDU).1016 Prime Ring Problem (DFS)
HDOJ(HDU).1016 Prime Ring Problem (DFS) [从零开始DFS(3)] 从零开始DFS HDOJ.1342 Lotto [从零开始DFS(0)] - DFS思想与框架 ...
- HDU 1258 Sum It Up(dfs 巧妙去重)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1258 Sum It Up Time Limit: 2000/1000 MS (Java/Others) ...
- hdu 1258 Sum It Up (dfs+路径记录)
pid=1258">Sum It Up Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (J ...
- hdu 1258 Sum It Up(dfs+去重)
题目大意: 给你一个总和(total)和一列(list)整数,共n个整数,要求用这些整数相加,使相加的结果等于total,找出所有不相同的拼凑方法. 例如,total = 4,n = 6,list = ...
- HDU 1258 Sum It Up (DFS)
Sum It Up Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total S ...
- HDU 1258 Sum It Up
Sum It Up Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total S ...
- 【HDOJ】1258 Sum It Up
典型的深搜,剪枝的时候需要跳过曾经搜索过的相同的数目,既满足nums[i]=nums[i-1]&&visit[i-1]==0,visit[i-1]==0可以说明该点已经测试过. #in ...
随机推荐
- 「日常训练」Brackets in Implications(Codeforces Round 306 Div.2 E)
题意与分析 稍微复杂一些的思维题.反正这场全是思维题,就一道暴力水题(B).题解直接去看官方的,很详尽. 代码 #include <bits/stdc++.h> #define MP ma ...
- Oracle-数据库增删改查基本操作
一.创建数据表 1).创建不存在的新表: create table tname( Data_Name Date_Type [default][默认值] );2).创建已存在表的副本 create ...
- 搭建hexo博客并部署到github上
hexo是由Node.js驱动的一款快速.简单且功能强大的博客框架,支持多线程,数百篇文章只需几秒即可生成.支持markdown编写文章,可以方便的生成静态网页托管在github上. 感觉不错. 前端 ...
- TCP/IP协议的学习笔记
1.OSI和TCP/IP的协议体系结构 OSI是开放系统互连参考模型,它的七层体系结构概念清楚,理论也比较完整,但它既复杂又不实用.而TCP/IP是一个四层的体系结构,它包含应用层.传输层.网际层和网 ...
- (原) MaterialEditor部- UmateriaEditor中 Node编译过程和使用(3)
@author: 白袍小道 转载说明原处 插件同步在GITHUB: DaoZhang_XDZ 说明 1.本篇是接着-----(原) MaterialEditor部- UmateriaE ...
- 最短路径算法(II)
什么??你问我为什么不在一篇文章写完所有方法?? Hmm…其实我是想的,但是博皮的加载速度再带上文章超长图片超多的话… 可能这辈子都打不开了吧… 上接https://www.cnblogs.com/U ...
- 动画效果 ObjectAnimator
学习了一下动画效果的使用,做一下笔记 ImageView imageView = findViewById(R.id.imageView); ObjectAnimator.ofFloat(imageV ...
- Windows下PHP安全环境的搭建
笔者一直在Windows环境下搭建PHP的运行环境,大大小小的运行环境用过不少,从开始的WAMP到后来的XAMPP以及PHPnow.WAMP和XAMPP都是继承mysql apache以及PHP库的运 ...
- Ext JS 6学习文档-第6章-高级组件
Ext JS 6学习文档-第6章-高级组件 高级组件 本章涵盖了高级组件,比如 tree 和 data view.它将为读者呈现一个示例项目为 图片浏览器,它使用 tree 和 data view 组 ...
- java知乎爬虫
好久没写博客了,前阵子项目忙着上线,现在有点空闲,就把最近写的一个爬虫和大家分享下,统计结果放在了自己买的阿里云服务器上(点此查看效果),效果如下: 程序是在工作之余写的,用了java 的webmgi ...