一开始想贪心,类似启发式搜索的感觉...后来觉得不行,而且很难写。

不如就枚举。可以通过0到2^W的中的每一个数的二进制形式来对应,第一行每个位置是否作为中心点放入十字格子的情况。

当此处为0时表示不放,1时表示放。

为什么只枚举第一行的所有情况就可以了呢。

因为第一行的情况确定之后,我们可以通过推理先改变第二行某些状态,然后再根据必须把第一行充满,可以确定第二排所有必须放十字块的位置。

生成该状态数之后,调用put函数,然后先影响下一行再通过结果来确定下一行。(这个算法的根基就是,处理每一行的时候要把上一行全部填满)

所以当到了最后一行被处理过之后,判断最后一行的合法性就可以了。

因为要处理很多位置...不想搞二进制很多事情了,就用bool数组来存状态了。

#include <iostream>
#include <algorithm>
using namespace std;
const int INF = 9999999;
bool map[20][20]={0};
bool cur[20][20]={0};
int H,W;void print(){cout<<"--------"<<endl;for (int i = 0; i < H; ++i){for (int j=0; j < W; ++j){cout<<cur[i][j];}cout<<endl;}cout<<"--------"<<endl;
}void copyMap(){for (int i = 0; i < H; ++i)for (int j=0; j < W; ++j)cur[i][j] = map[i][j];
}void init(){cin>>H>>W;for (int i = 0; i < H; ++i){for (int j = 0; j < W; ++j){int l;cin>>l;map[i][j] = l%2; //偶数为0 奇数为1
        }}
}//计算k的二进制中有多少个1
int getOnes(int k){int ans = 0;while(k>0){if((k&1)) //如果最右侧是1ans++;k = k>>1;//每次扔出最右的一位;
    }return ans;
}void put(int lineId, int state){//枚举时我们认为一个 状态数state 每个位置的 0表示不放 1表示放 那么进行填补for (int i = 0; i < W ; ++i) //从第一排第0个位置 到第W-1个
    {if(state&(1<<i)){//表示是放的 则对两边及下方的进行填写if(lineId>=1)//可以不用写cur[lineId-1][i] = !cur[lineId-1][i];cur[lineId][i] = !cur[lineId][i];if(i>=1)cur[lineId][i-1] = !cur[lineId][i-1];cur[lineId][i+1] = !cur[lineId][i+1];cur[lineId+1][i] = !cur[lineId+1][i];}}
}int build(){bool have = false;int res = INF;//首先要对第一排的放十字的所有可能情况进行枚举//然后根据第一行的摆放情况 可以确定第二行的摆放,依次决定第三行.....for (int i = 0; i < (1<<W); ++i)//一共有2^W种放的情况
    {//每次枚举前先进行copy 不能直接在map上进行修改
        copyMap();int cnt = getOnes(i);//对放的十字的个数进行记录put(0,i);//print();//第一排做完了 我们来根据第一排的情况 确定接下来每一排必须放十字的位置for (int k = 1; k < H; ++k){int curState = 0;//生成状态数 用来进行调用put函数for (int j = 0; j < W; ++j){if(cur[k-1][j])//如果上一行的这个地方是1 即是奇数 则肯定要在以这一行的这个位置为中心进行填补curState += (1<<j);}cnt += getOnes(curState);put(k,curState);}//放完之后要检查最后一行是不是已经被填满 如果是的话 则说明全体都被填成偶数bool ok = true;for (int j = 0; j < W; ++j){if(cur[H-1][j]){ok = false;break;}}if(ok){have = true;res = min(res,cnt);}}if(!have)res = -1;return res;
}int main(int argc, char const *argv[])
{init();cout<<build()<<endl;return 0;
}

转载于:https://www.cnblogs.com/yuchenlin/p/sjtu_oj_1391.html

【算法学习笔记】74. 枚举 状态压缩 填充方案 SJTU OJ 1391 畅畅的牙签袋(改)...相关推荐

  1. 【算法学习笔记】67.状态压缩 DP SJTU OJ 1383 畅畅的牙签袋

    思想来自:http://blog.pureisle.net/archives/475.html 主要思想是用1和0来表示是否被填,然后根据两行之间的状态关系来构建DP方程. 1.首先初始化第一行 计算 ...

  2. 【算法学习笔记】35.高精度 竖式乘法 SJTU OJ 1274

    Description 输入a,b 输出a*b的竖式乘法,格式见样例. Sample Input1 11 9 Sample Output1 119 -- 99 Sample Input2 10 10 ...

  3. 两个字符串的最长公共子序列长度_算法学习笔记(58): 最长公共子序列

    (为什么都更了这么多篇笔记了,这时候才讲这么基础的内容呢?因为我本来以为LCS这种简单的DP不用讲的,结果CF不久前考了LCS的变式,然后我发现由于自己对LCS一点都不熟,居然写不出来 ,于是决定还是 ...

  4. 【基础】基础算法学习笔记(状态空间)

    基础算法学习笔记(状态空间) 一.状态空间 1.定义(什么是状态空间):一个实际问题的各种可能情况构成的集合.(解释:为什么需要算法来和程序来处理问题?如果一道题可以手算得到答案,换句话说就是存在通过 ...

  5. Python最优化算法学习笔记(Gurobi)

    微信公众号:数学建模与人工智能 github地址:https://github.com/QInzhengk/Math-Model-and-Machine-Learning Python最优化算法学习笔 ...

  6. 数据结构与算法学习笔记——链栈

    数据结构与算法学习笔记(C语言) 链栈 在开始链栈的学习之前,我们先实现一下上一篇文章中提到的检查括号匹配的小程序,鉴于水平有限,本人就随便写一下代码好了,目标仅限于对功能的实现. /*用顺序栈这种数 ...

  7. 区块链学习笔记15——ETH状态树

    区块链学习笔记15--ETH状态树 学习视频:北京大学肖臻老师<区块链技术与应用> 笔记参考:北京大学肖臻老师<区块链技术与应用>公开课系列笔记--目录导航页 引入 要实现的功 ...

  8. 数据结构与算法学习笔记15:最大流问题 / 二分图 / 有权无权二分图的匹配 / 匈牙利算法 / 银行家算法 / 稳定婚配

    数据结构与算法学习笔记15:最大流问题 / 二分图 / 有权无权二分图的匹配 / 匈牙利算法 / 银行家算法 / 稳定婚配 引入小题:最短路径 最大流问题(maximum flow problem) ...

  9. Parse算法学习笔记

    Parse算法学习笔记 Parse算法是一种自底向上的语法分析算法,其主要应用于编译器中的语法分析阶段.相比于其他语法分析算法,Parse算法具有简单.高效的特点.本篇文章将详细介绍Parse算法的原 ...

最新文章

  1. ATS无法缓存QQ音乐的音频文件问题
  2. 设计模式——创建型模式
  3. Windows事件等待学习笔记(二)—— 线程等待与唤醒
  4. Vue——Vue-Router的push和replace方法[Uncaught (in promise) Error]解决方案
  5. 关于如何将轮播图在移动端和pc端自适应的操作
  6. 红帽企业linux4参考指南读书笔记-GRUB引导器
  7. 3D重建传统算法对比深度学习,SFU谭平:更需要的是二者的融合
  8. bat执行java文件_.bat文件执行java程序
  9. 顺序表查找及其优化(Java)
  10. 阶段3 1.Mybatis_09.Mybatis的多表操作_6 分析mybatis多对多的步骤并搭建环境
  11. GridView中如何取得隐藏列的值
  12. 24点之5 7 7 11
  13. 实现1.1、1.1.1的多级编号文档排版
  14. 使用react 写一个 仿淘宝 图片放大镜效果
  15. 关于灰色关联分析以及灰色预测初步理解
  16. 步进电动机速度调节和方向控制实验
  17. 《Splunk智能运维实战》——1.2 索引文件和目录
  18. 百度API提交Java版,让你的网站快速收录提高排名
  19. 古代艺术家签合同,都狡猾着呢
  20. Vue.js 电话验证规则(包括座机,带区号和不带区号,手机)

热门文章

  1. 行深智能亮相乌镇互联网大会,荣获直通乌镇全球互联网大赛一等奖
  2. 鼠标测试cps软件,人最多鼠标cps是多少?
  3. springside4配置环境时无法下载到两个核心包
  4. 随机事件和概率及概率的性质
  5. QTextToSpeech 文本转语音输出
  6. 迁移系统:换电脑或者硬盘转移磁盘文件的方法!
  7. 寻找怪数:有一种奇怪的自然数,它的比其本身小的所有因子之和等于它本身,例如:6=1+2+3,其中1、2、3都是6的因子,编程找出整数N之内的所有怪数。
  8. 如何激发员工的积极性
  9. 比较好用的服务器和网站在线测速工具分享
  10. 生物信息学Bioinformatics学习笔记(三)-高通量测序