学校测试-2015-03-01

记得以前做N皇后问题见到过二进制+位运算优化的方法, 今天的搜索题第三题和第四题都可以用到二进制和位运算. 就只做了这两个题目.


题目三

描述

传递游戏(pass)

Description

n个人在做传递物品的游戏,编号为1-n。

游戏规则是这样的:开始时物品可以在任意一人手上,他可把物品传递给其他人中的任意一位;下一个人可以传递给未接过物品的任意一人。

即物品只能经过同一个人一次,而且每次传递过程都有一个代价;不同的人传给不同的人的代价值之间没有联系;

求当物品经过所有n个人后,整个过程的最小总代价是多少。

Input Format

第一行为n,表示共有n个人(16>=n>=2);

以下为n*n的矩阵,第i+1行、第j列表示物品从编号为i的人传递到编号为j的人所花费的代价,特别的有第i+1行、第i列为-1(因为物品不能自己传给自己),其他数据均为正整数(<=10000)。

Output Format

一个数,为最小的代价总和。


分析

  • 状压DP, 二进制表示状态(点到过或没到过), 位运算实现查找和更新等操作
  • f[i][k]表示状态为 k 并且最后停留在 i 点时的最小代价
  • => min{f[i][(1<<n)+1], (0<=i<n)}
  • 转移 :

    枚举状态 k : 0 -> (1 << n) - 1

    枚举要更新的结点 i : 0 -> n-1

    枚举中间结点 j : 0 -> n-1, (i != j)

    如果满足 在状态 k 中第 i 的位置为 0, 而第 j 的位置为 1, 那么就可以用 j 去更新 i.

  • 核心 :
      if(i != j && (k&(1 << j)) && !(k&(1 << i)))
                f[i][k^(1 << i)] = min(f[i][k^(1 << i)], f[j][k] + d[j][i]);
  • 初始化

    f[i][1 << i] = 0, (0<=i<n)

    表示从任意点出发


代码

https://code.csdn.net/snippets/609746


题目四

描述

皇后守卫(queen)

Description

给一个N * M的棋盘,棋盘上的有些格子被打上了标记。现在需要在其中放置尽量少的皇后,使得所有被打上标记的格子至少被某一个皇后攻击或占据到。皇后之间可以互相攻击。

Input Format

输入最多15组数据。

每组数据第一行包含两个整数N和M(1 < N, M < 10),以下为一个N行M列的棋盘,其中打上标记的格子用‘X’表示,其它格子用‘.’表示。

输入以一个0结尾。

Output Format

对于每组数据,输出一个数表示最少需要使用的皇后数目。


分析

  • 二进制+位运算优化+普通最优化剪枝的 dfs
  • void dfs(int x, int row, int ld, int rd, int* k, int c)

    x => 当前行

    row => 这一行被列控制下的上禁止放的位置

    ld => 这一行被左对角线控制下的不能放的位置

    rd => 这一行被右对角线控制下的不能放的位置

    k => 数组, 表示当前所有被覆盖的位置, 每一行都是用二进制表示的, 所以数组只需开一维

    c => 计数变量, 已经放的皇后数

    主函数调用dfs(0, 0, 0, 0, k, 0) // k 初始化全为 0

  • 函数执行过程

    如果该状态下满足了需要, 直接更新答案后返回

    如果所以行已经考虑完了(x >= n), 直接返回

    最优化剪枝 : 如果当前 c 不比已经记录的 ans 更优, 直接返回

    从当前行中选可以放置皇后的地方开始放皇后, 继续dfs到下一层

    该行不放皇后, dfs到下一层

  • 许多精巧的位运算 :
    • 在 row, ld, rd 限制下取出所有可以放置皇后的地方 => pos = ((1<<n)-1) & ~(row | ld | rd)

      解释 : row | ld | rd表示所有不可以放置皇后的地方, 取反后表示所有可以放置皇后的地方, 再并一下去除前面多余的1

    • 判断是否满足条件, 标记的地方都被覆盖到

      枚举 x, 如果所有 (k[x]&tar[x]) == tar[x] 说明满足

      解释 : tar[x]表示第 x 行需要被覆盖的二进制状态. 只有当 tar[x] 为 1 的地方 k[x] 也为 1 才满足

    • 更新状态, 在第 x 行二进制下 p 位置放置皇后对原可覆盖状态 k 的影响
    void update(int x, int p, int* k)
    {
    k[x] = upperlim;
    for(int i = 1; x-i >= 0; i++) {
        if((p<<i) < upperlim) k[x-i] |= (p<<i);
        if((p>>i) > 0) k[x-i] |= (p>>i);
        k[x-i] |= p;
    }
    for(int i = 1; x+i < n; i++) {
        if((p<<i) < upperlim) k[x+i] |= (p<<i);
        if((p>>i) > 0) k[x+i] |= (p>>i);
        k[x+i] |= p;
    }
    }

    解释 : upperlim = (1 << n) - 1

    首先 x 行应该全变为 1, 也就是 k[x] 状态为 upperlim

    再考虑对角线和列

    对p的解释 : p 的二进制中只有一位为 1, 也就是皇后所在列的那一位


代码

https://code.csdn.net/snippets/609744



时间: 2024-11-05 19:03:48

学校测试-2015-03-01的相关文章

深入浅出WPF之Binding -- 笔记(2015.03.01)

当使用一个集合或DataView作为Binding的源时,如果想把它的默认元素当作Path使用,则需要使用"/"语法:如果集合元素的属性仍然还是一个集合,又想把子级集合中的元素当作Path,则可以使用多级斜线的语法(即一路"斜线"下去): 事例一: XAML: <StackPanel>        <TextBox x:Name="textBox1" BorderBrush="Black" Margin=&

2015科研 01. 计划

还什么都不会就报名了科研 试试看吧!今年结尾能不能做出成果来   l 主要研究内容: 1)Android应用程序UI设计. 2)基于Android平台的提醒服用药物软件的实现. 3)软件的基本功能: 1. 用户可以自主添加药物,输入药物名称,选择药物形状.颜色.用量等药物基本信息. 2. 用户可以输入药物的使用频率,并且设置药物的使用时间提醒. 3. 用户可以查看个人所需的所有药物. 4. 用户可以查看个人当天需要使用的药物及记录. 5. 用户可以备份资料,导入资料. l 研究的难点和创新点:

第一金早评 - 2015年01月07日-晨早快訊

每日金市速遞 (2015年01月07日) 谢权东 先生 上日9999 金粒賣出價每両 HKD 12590 金粒賣出價資料參考周生生,周大福 即日投資策略: 黃金日線圖上分析,日線收3連陽,K線沿布林帶中軌和上軌之間運行,金價日內大漲,布林帶有向上開口跡象,布林中軌向上翹頭,短週期均線指標金叉向上,MACD快慢線死叉於0軸下方金叉,有上穿0軸趨勢,紅柱放量. 從4小時來看,布林帶向上開口,金價處於布林上軌1220與MA5-1215之間震盪往上,短週期均線指標金叉向上,MACD快慢線於0軸附近形成金

盼来的仓促果实?腾讯官方Android QQ详测(2010-04-01 03:01)

1 腾讯Android QQ评测;现状与登陆体验 前言: 腾讯QQ估计没有什么网友不认识它,但是它在手机平台上的发展并没有如电脑应用版本更新得那么积极,一个塞班S60 v5的QQ足够吊人胃口.时至近日,腾讯低调地发布了QQ for Android Beta 1.0版(也许正是忙于Android而忽略塞班S60 v5).作为官方御用的版本,让人等待了近一年的时间,过程中"民间"也悄然出现了不少相对完美的QQ版本,如aQQ.WebQQ等.腾讯方面如是说:"腾讯公司针对日渐增多的A

LoadRunner测试结果分析01 转载至zhangzhe的新浪博客

LoadRunner测试结果分析之我见 LoadRunner生成测试结果并不代表着这次测试结果的结束,相反,这次测试结果的重头戏才刚刚开始.如何对测试结果进行分析,关系着这次测试的成功与否.网上关于LoadRunner测试结果如何分析的介绍相当匮乏,在总结他人的观点和自己的实验体会基础上来介绍如何进行LoadRunner测试结果分析. 1. LoadRunner测试结果分析的第一步应该是查看分析综述(Analysis Summary),其包括统计综述(Statistics Summary).事务

iOS 学习笔记 六 (2015.03.28)常见错误

2015.03.28 1. property's synthesized getter follows Cocoa naming convention for returning 'owned' objects You own any object you create You create an object using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy” (for example, 

2015年01月09日_安装archlinux中一些注意事项

一直以来是用win或ubuntu办公.新手不懂高手怎么那么喜欢linux,做完一个大项目后才发觉一个快速运行的系统多么重要.ubuntu办公虽然快一些,但是在办公方面感觉还是略差一节,现决定使用archlinux及轻量级桌面,把所有能用得起的物理资源全部用在工作软件方面.2015年01月09日在安装时出现了一些小问题,现记录如下,供以后自己及有心人查阅. 1. arch wiki文档中可切换到中文查看.确保顺序没错 2. vi中搜索关键字:  /vi vi中的剪切一行:dd vi中的复制一行:y

OpenSCAD 2015.03的大变化,更方便了。

OpenSCAD 2015.03出来了,有几个大的变化: 1.增加工具按钮,操作起来更方便,尤其是在Mac OS X的窗口全屏模式下. 2.坐标的标尺显示尺寸的刻度,这个对3D打印的模型设计很方便. 3.代码编辑器支持代码块折叠和自动缩进等专业代码编辑器的一些特征了. 注意:一定要自己下最新版的才有这个功能哦,我用mac port装的最新才14.03,没有这些个功能. 顺便唠叨下:到http://www.thingiverse.com,在搜索框输入openscad,可以找到大量的采用OpenSC

华为上级测试 2015

描述: 输入一组大于等于0的整数,根据从大到小排序后输出,如果排序后有连续整数时,只输出连续数中最大和最小的两个数.输入的所有整数各不相同,即不用考虑两个整数相同的情况. 运行时间:无限制 内存限制:无限制 输入:一组大于等于0的整数,不考虑非法输入,各个整数之间以逗号(",")分隔,输入总数长度小于100个字节. 输出:排序后,各个整数之间以逗号(",")分隔. 样例输入:1,4,7,2,5,8,9,11 样例输出:11,9,7,5,4,2,1 描述:输入一组大于

2015.03.17,外语,&lt;Word Power Made Easy&gt; 01 “如何讨论人格特点”学习笔记 SESSIONS 1

本来这些章节都是在一两年前学习的,现在趁给友人送书的机会,重新做一次笔记,也再次复习一遍. 蓝色字体仍然是注释,粗体主要是标题和要背诵的单词.红色的部分是自己的心得.我比较关注发音,所以除非是非常简单和直白的发音,我一般会查询词典得到准确的读音音标,并放上来. TEASER PREVIEW (Teaser 片头,预告片,玩笑 Teaser trailer:预告片) 如何描述这些人格: 只关心自己的福利.(solely:adv.单独的,独自的,完全['so?lli])(welfare:n.福利,幸