计蒜客蓝桥杯模拟赛五J. 程序设计:放置守卫
在一张 n 行 m 列的方格地图上放置一些守卫,每个守卫能守护上、左、右三个方向上相邻的方格和自己所在的方格。如下图,红色的方格放置守卫,绿色的方格为该守卫守护的区域。

现在要求在地图上放置若干个守卫,让每个方格至少被一个守卫守护(可以同时被多个守卫守护),但是有些方格上不能放置守卫(这个方格也需要被守护),求出最少需要多少个守卫才能满足条件。
输入格式
第一行输入两个整数 n, m。
接下来输入一个 n×m 的矩阵。矩阵中元素为 0 表示该位置不能放置守卫,为 1 表示该位置能放置守卫。元素之间用空格隔开。
数据约定: 所有数据保证一定有一种方案满足条件。
对于 20% 的数据: 1≤n,m≤5;
对于 50% 的数据: 1≤n≤20,1≤m≤10;
对于100% 的数据: 1≤n∗m≤1000,1≤m≤15。
输出格式
输出最少需要放置的守卫数量。

没有打这个。。不过学校群有人发出来了。做了下,没得交,大概思路应该是对的
做法:

我们做一个dp,假设格子移动到了图中标记为1的地方,我们定义dp[now][sta]为当移动到这个格子,而且(4,3,2,1,0)的状态为sta的二进制表示(顺序也是一样的,1表示已放置,0表示未放置),并且这个分界线以上的全部被放置了的最小放置守卫数,这个分界线是这样的,当转移到(i,j)时,分界线就是(i,0)(i,1)...(i,j)(i-1,j)(i-1,j+1)..(i-1,m-1)转移比较简单,初始化第一个格子的时候,我们知道第一个格子是没有格子的,但是我们把那里当成已被守卫的格子就好了所以就是dp[now][(1 << m+1) - 2] = 0,其他定义为-1。
举个例子吧,下面的数字外面一层表示行列数,里面的表示分界线
0 1 2 3
0 _ _ 3 4
1 0 1 2 _
图1
我们知道我们当前是转移到(1,2)这个位置的,当这个位置可以放守卫,我们选择放一个守卫之后
0 1 2 3
0 _ _ _ 4
1 0 1 2 3
图2
现在转移到下一个格子了,但是刚刚在(1,2)放了守卫,所以(1,1)(1,2)(1,3)(0,2)这四个位置的状态都要变成了1,所以我们的sta需要或一个(1 << (j-1))(1 << (j))(1 << (j+1))如果j-1小于0就不用了,(0,2)这个位置已经到了分界线外。所以如果当前格子上面是没有守卫的,就必须放一个。因为我们定义的dp是分界线上必须全部被守卫。
如果当前格子有守卫,我们可以选择不放,如果不放的话我们需要把sta^(1 << (j + 1)),因为我们可以知道图1的分界线3转移到下一个的图2时,这个位置原本是没有守卫的,所以要置为0。
这上面的转移是一种情况,但是当转移需要换行的时候,转移的式子会有所改变,不过手推很容易推出来。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
#include <time.h>
#include <string>
#include <stack>
#include <set>
#include <map>
#include <iostream>
#include <bitset>
#include <algorithm>
using namespace std;
#define MP make_pair
#define rep(i,n) for(int i = 0; i < (n); i++)
#define per(i,n) for(int i = (n-1); i >= 0; i--)
#define rep1(i,n) for(int i = 1; i <= (n); i++)
#define per1(i,n) for(int i = (n); i > 0; i--) #define PB push_back
#define mst(a,b) memset((a),(b),sizeof(a))
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> Pii;
typedef vector<int> Vi;
typedef vector<Pii> Vii;
const int inf = 0x3f3f3f3f;
const LL INF = (1uLL << ) - ;
const LL mod = ;
const int N = 1e5 + ;
const double Pi = acos(-1.0);
const int maxn = ( << ) + ;
const uLL Hashmod = ;
int dp[][maxn];
int maz[][];
int n, m;
inline bool up(int sta, int pos) {
return (sta & ( << (pos + ))) != ;
}
inline void uMin(int &A, int B) {
if(B == -)return;
if(A == -)A = B;
else A = min(A, B);
}
inline int Set(int sta, int pos) {
if(pos - >= )sta |= ( << (pos - ));
sta |= ( << pos);
sta |= ( << (pos + ));
if(pos == m - ) {
sta <<= ;
sta %= ( << (m + ));
}
return sta;
}
inline int noSet(int sta,int pos){
if(pos != m - )sta ^= ( << (pos + ));
else sta <<= ,sta %= ( << (m + ));
return sta;
}
//inline void show(int x) {
// putchar('0' + x % 2);
// if(x > 1)show(x / 2);
//}
int main() {
#ifdef local
freopen("input", "r", stdin);
//freopen("w","w",stdout);
#endif
ios::sync_with_stdio();
cin.tie();
cin >> n >> m;
rep(i, n)rep(j, m)cin >> maz[i][j];
int nx = , now = ;
mst(dp[nx], -);
dp[nx][( << (m + )) - ] = ;
rep(i, n) {
rep(j, m) {
swap(nx, now);
mst(dp[nx], -);
rep(sta, ( << (m + ))) {
if(dp[now][sta] != -) {
if(up(sta, j)) uMin(dp[nx][noSet(sta,j)], dp[now][sta]);
if(maz[i][j]) uMin(dp[nx][Set(sta, j)], dp[now][sta] + );
}
}
}
}
int ans = dp[now][( << (m + )) - ];
uMin(ans,dp[nx][( << (m + )) - ]);
cout << ans << endl;
}
...因为并没有找到可以提交的地方,所以代码也只是随便测了几组,不过思路好像没什么问题,如果找到代码错误的话可以留言或者私信交流一下
计蒜客蓝桥杯模拟赛五J. 程序设计:放置守卫的更多相关文章
- 计蒜客蓝桥杯模拟赛 后缀字符串:STL_map+贪心
问题描述 一天蒜头君得到 n 个字符串 si,每个字符串的长度都不超过 10. 蒜头君在想,在这 n 个字符串中,以 si 为后缀的字符串有多少个呢? 输入格式 第一行输入一个整数 n. 接下来 ...
- 计蒜客 蓝桥杯模拟 瞬间移动 dp
在一个 n \times mn×m 中的方格中,每个格子上都有一个分数,现在蒜头君从 (1,1)(1,1) 的格子开始往 (n, m)(n,m) 的格子走.要求从 (x_1,y_1)(x1,y1 ...
- 计蒜客 蓝桥模拟 B.素数个数
用 0,1,2,3⋯70,1,2,3 \cdots 70,1,2,3⋯7 这 888 个数组成的所有整数中,质数有多少个(每个数字必须用到且只能用一次). 提示:以 000 开始的数字是非法数字. 代 ...
- 计蒜客 蓝桥模拟 A. 结果填空:矩阵求和
给你一个从 n×nn \times nn×n 的矩阵,里面填充 111 到 n×nn \times nn×n .例如当 nnn 等于 333 的时候,填充的矩阵如下. 1 1 2 3 2 4 5 ...
- 计蒜客 蓝桥模拟 I. 天上的星星
计算二维前缀和,节省时间.容斥定理. 代码: #include <cstdio> #include <cstdlib> #include <cstring> #in ...
- 计蒜客 蓝桥模拟 H. 封印之门
Floyd算法,最短路,判断a,b是否相等. 代码: #include <cstdio> #include <cstdlib> #include <cstring> ...
- 计蒜客 蓝桥模拟 F. 结果填空:数独
代码: #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream& ...
- 计蒜客 蓝桥模拟 G. 数列求值
递归式移项得Ai+1 = 2Ai + 2Ci - Ai-1; 1.A2 = 2A1 + 2C1 - A0; 2.A3 = 2A2 + 2C2 - A1; . . . n.An+1 = 2An + 2C ...
- 计蒜客 2018南京网络赛 I Skr ( 回文树 )
题目链接 题意 : 给出一个由数字组成的字符串.然后要你找出其所有本质不同的回文子串.然后将这些回文子串转化为整数后相加.问你最后的结果是多少.答案模 1e9+7 分析 : 应该可以算是回文树挺裸的题 ...
随机推荐
- 老李分享:开发python的unittest结果输出样式
老李分享:开发python的unittest结果输出样式 Python的unittest结果命令行输出,格式比较乱.为了提高格式输出的可读性,实现可以不同的颜色标识.所以准备扩展Python的un ...
- 爬虫入门系列(一):快速理解HTTP协议
4月份给自己挖一个爬虫系列的坑,主要涉及HTTP 协议.正则表达式.爬虫框架 Scrapy.消息队列.数据库等内容. 爬虫的基本原理是模拟浏览器进行 HTTP 请求,理解 HTTP 协议是写爬虫的必备 ...
- 看Lucene源码必须知道的基本概念
终于有时间总结点Lucene,虽然是大周末的,已经感觉是对自己的奖励,毕竟只是喜欢,现在的工作中用不到的.自己看源码比较快,看英文原著的技术书也很快.都和语言有很大关系.虽然咱的技术不敢说是部门第一的 ...
- 在ASP.NET Core中使用Apworks开发数据服务:对HAL的支持
HAL,全称为Hypertext Application Language,它是一种简单的数据格式,它能以一种简单.统一的形式,在API中引入超链接特性,使得API的可发现性(discoverable ...
- JS数组根据属性来实现排序
var data = [{ name: "zhao", age: }, { name: "qian", age: }, { name: "sun&qu ...
- maven私服搭建nexus介绍(二)
1.各个仓库介绍 Hosted:宿主仓库 主要放本公司开发的SNAPSHOTS测试版本,RELEASES正式发行版.合作公司第三方的jar包. Proxy:代理仓库 代理中央仓库:代理Apache下测 ...
- png、jpg、gif三种图片格式的区别
png.jpg.gif三种图片格式的区别 2014-06-17 为什么想整理这方面的类容,我觉得就像油画家要了解他的颜料和画布.雕塑家要了解他的石材一样,作为网页设计师也应该对图片格式的特性有一定 ...
- JS中substring与substr的区别
Substring: 该方法可以有一个参数也可以有两个参数. (1) 一个参数: 示例: var str=“Olive”: str.substring(3); 结果:“ve” 说明:当substri ...
- ASP.NET MVC4 微信公众号开发之网页授权(二):通过公众号AppID(应用ID)和AppSecret(应用密钥)取得网页授权openid
ASP.NET MVC4 微信公众号开发之网页授权(一):搭建基础环境 通过了上一篇文章我们已经搭建好了基础开发大环境,现在打开开发环境这里我用的是 vs2013,通过如下方式: 拼接请求链接重定向到 ...
- stm32中的延时函数
//粗延时函数,微秒 void delay_nus(u16 time) { u16 i=0; while(time--) { i=10; //自己定义 while(i--) ; } } //毫秒级的 ...