- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
the Searching Method Alfred Yuan(2006) Info. RUC 搜索的本质 一句话的解释:在所有的情况中寻找符合要求的情况 类比的说法:搜索即一种特殊枚举 辨别:搜索是有选择的、有一定效率的,枚举是无选择的、低效率的 题目引入:傻大木买军火 要求: 1. 傻大木共购买了三种武器:2万美元一个的木瓜手雷,6万美元一支的啊卡卡47型冲锋枪和1万美元一个的大杀器。 2. 三种武器的数量各不相同。 3. 傻大木购买的木瓜手雷的个数在大杀器个数和冲锋枪支数之间。 4. 木瓜手雷必须成对购买。 5. 为了图吉利,傻大木购买的大杀器个数的尾数是8(如8,48等)。 6. 如果冲锋枪的支数是一位数,那么木瓜手雷的个数一定是两位数。(但如果冲锋枪的支数不是一位数,那么木瓜手雷的个数可能是任何数。) 7. 傻大木的n万元可能恰好花完了,也可能没花完,但一定花了九成以上。 题目的简单思路 for size_bomb = min_possible to max_possible for size_kaka = min_possible to max_possible for size_bigkiller = min_possible to max_possible If Accept( size_bomb , size_kaka , size_bigkiller) { Output( size_bomb , size_kaka , size_bigkiller ) } 总结基本思路 枚举所有可能的情况,再在所有可能的情况中寻找符合要求的情况 同时我们可以发现,这道题目的变量数目是3(炸弹、咔咔、大杀器),是一个常量,也就是说,三层循环就可以枚举出所有可能的情况,那么对于变量数目为一个变量n的情况呢? 不妨看下一道题目 深入:计算正行列式项 由键盘输入n,和一个n*n的矩阵,输出所有计算行列式时要用到的正项之和。 For example : Input: 2 1 2 3 4 Output: 4 其中p1,p2,…,pn是1,2,…,n的排列,t是排列p1,p2,…,pn的逆序数, 表示对1,2,…,n的所有排列(共n!个)求和。 在n个数的1,2,…,n的一个全排列中,若两个数的前后次序和标准排列({1,2,…,n}为标准排列)不一致,则称这两个数构成一个逆序。一个排列中逆序的总的个数称为这个排列的逆序数,记为t。 解题思路 生成所有排列,即确定n个变量:j1、j2……jn的值 对于每一组j1……jn,计算对应逆序数 用求得的逆序数结合输入的矩阵计算出该项的值t 若t0 加到和sum中 若t0 不做任何处理 最后输出sum 总结大概的代码: for j1 = 1 to n do for j2 = 1 to n do …… for jn = 1 to n do if 任意两个ji,jk互不相等 { t = calc( j1 , j2 …… jn) //计算逆序数,并返回(-1)t t = t*a[1][j1] * a[2][j2] * … * a[n][jn] if ( t 0 ) sum = sum + t ; } cout sum ; 我们发现: 要使用n层循环,也就是说,循环的个数是动态的 如何解决这个问题? 使用递归的方法,n层循环转化成n层递归 具体方法,看如下的程序 bool used[MAXN] ; // 用来实现j1...jn互不相同 int j[MAXN] ; int t ; int sum ; void Search( int k ) { if ( k n ) { t = calc(); // 对于储存在数组j中的n个变量计算逆序数 int i ; for ( i = 1 ; i = n ; i++ ) t = t * j[i] ; // t = t * j1 * j2 * ... * jn if (t 0) sum += t ; // sum = sum + t return; } for ( j[k] = 1 ; j[k] = n ; j[k] ++ ) if ( !used[j[k]] ) // 判断j[k]是否能取 { used[j[k]] = true; Search( k + 1 ); used[j[k]] = false; } } 解决了这个问题我们就可以给出搜索问题的模版程序 int j[MAXN] // MAXN是可能的参数个数 void Search( int k ) { if ( k
文档评论(0)