题目背景

  $NEWorld$作为一个$3D$游戏,对渲染(图形绘制)的效率要求极高。当玩家扩大视野范围时,可见的方块面数量将会迅速增多,以至于大量的顶点处理很快就成为了图形管线中的瓶颈。乔猫想了想,决定在大量绘制前,预处理一些相邻且有着相同材质的方块面——将许多小的面合成一个大的面,便可以在不改变渲染结果的同时减少很多顶点数量了吧......


题目描述

  给定一个$N\times M$的网格,每个格子上写有$0$或$1$。现在用一些长方形覆盖其中写有$1$的格子,长方形的每条边都要与坐标轴平行。要求:每个写着$1$的格子都要被覆盖,长方形不可以重叠(重复绘制也多少会增加性能开销),也不能覆盖到任何一个写着$0$的格子(不然绘制结果就不正确了)。请问最少需要多少长方形?


输入格式

  输入文件名为$merging.in$。
  输入文件第一行两个正整数$N,M$,表示网格大小为$N$行$M$列。
  接下来的$N$行,每行$M$个正整数$A_{ij}$(保证均为$0$或$1$),其中第$i$行$j$列的正整数表示网格$i$行$j$列里填的数。


样例

样例输入:

4 4
1 1 1 0
1 1 1 1
0 0 1 1
0 0 1 1

样例输出:

3


数据范围与提示

样例解释:

一种可行的覆盖方案(粗线表示分割线):

对于$30\%$的数据:$N,M\leqslant 5$。
对于$100\%$的数据:$N\leqslant 100,M\leqslant 8$。

数据范围:

对于$30\%$的数据:$N,M\leqslant 5$。
对于$100\%$的数据:$N\leqslant 100,M\leqslant 8$。


题解

观察$M$的范围,可以看出来应该是一个状压(当也有可能是轮廓线$DP$,甚至是插头$DP$)。

采用$8$进制压位表示每一位为起点的连续段的终点是几即可。

注意如果终点是$1$,那么起点也一定是$1$即可。

时间复杂度:$\THeta(N\times M\times 2^M)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
int N,M;
int A[102][9];
bool vis[9][9];
int dp[102][150000];
vector<int> vec[102];
int ans=0x3f3f3f3f;
void dfs(int x,int y,int pre,int state)
{
if(y>M){if(!pre)vec[x].push_back(state);return;}
if(A[x][y])
{
if(!pre)
{
dfs(x,y+1,1,state|(1<<((y-1)<<1)));
dfs(x,y+1,0,state|(3<<((y-1)<<1)));
}
else
{
dfs(x,y+1,1,state);
dfs(x,y+1,0,state|(2<<((y-1)<<1)));
}
}
else
{
if(pre)return;
else dfs(x,y+1,0,state);
}
}
int main()
{
memset(dp,0x3f,sizeof(dp));
scanf("%d%d",&N,&M);
for(int i=1;i<=N;i++)
for(int j=1;j<=M;j++)
scanf("%d",&A[i][j]);
for(int i=1;i<=N;i++)dfs(i,1,0,0);
for(int j=0;j<vec[1].size();j++)
{
int state=vec[1][j],res=0;
for(int i=1;i<=M;i++)
{
int flag=(state^(state>>(i<<1)<<(i<<1)))>>((i-1)<<1);
if(flag==1||flag==3)res++;
}
dp[1][state]=res;
}
for(int i=1;i<=N;i++)
{
for(int j=0;j<vec[i].size();j++)
{
int state=vec[i][j];
memset(vis,0,sizeof(vis));
for(int k=1,l;k<=M;k++)
{
switch((state^(state>>(k<<1)<<(k<<1)))>>((k-1)<<1))
{
case 1:l=k;break;
case 2:vis[l][k]=1;break;
case 3:vis[k][k]=1;break;
}
}
for(int k=0;k<vec[i+1].size();k++)
{
int staet=vec[i+1][k],res=0;
for(int l=1,h;l<=M;l++)
{
switch((staet^(staet>>(l<<1)<<(l<<1)))>>((l-1)<<1))
{
case 1:h=l;break;
case 2:res+=!vis[h][l];break;
case 3:res+=!vis[l][l];break;
}
}
dp[i+1][staet]=min(dp[i+1][staet],dp[i][state]+res);
}
}
}
for(int i=0;i<vec[N].size();i++)ans=min(ans,dp[N][vec[N][i]]);
printf("%d",ans);
return 0;
}

rp++

[CSP-S模拟测试]:邻面合并(状压DP)的更多相关文章

  1. [CSP-S模拟测试]:点亮(状压DP+树上背包DP)

    题目传送门(内部题121) 输入格式 第一行,一个正整数$n$. 第二行,$n-1$个正整数$p_2,p_3,...,p_n$.保证$p_u$是在$1$到$u-1$中等概率随机选取的. 接下来$n$行 ...

  2. 【CSP模拟赛】Adore(状压dp 二进制)

    题目描述 小w偶然间见到了一个DAG.这个DAG有m层,第一层只有一个源点,最后一层只有一个汇点,剩下的每一层都有k个节点.现在小w每次可以取反第i(1<i<n-1)层和第i+1层之间的连 ...

  3. 【noip模拟赛5】细菌 状压dp

    [noip模拟赛5]细菌   描述 近期,农场出现了D(1<=D<=15)种细菌.John要从他的 N(1<=N<=1,000)头奶牛中尽可能多地选些产奶.但是如果选中的奶牛携 ...

  4. 【BZOJ4565】【HAOI2016】字符合并 [状压DP][区间DP]

    字符合并 Time Limit: 20 Sec  Memory Limit: 256 MB[Submit][Status][Discuss] Description 有一个长度为 n 的 01 串,你 ...

  5. [CSP-S模拟测试]:装饰(状压DP)

    题目传送门(内部题114) 输入格式 第一行一个正整数$n$. 接下来一行$n-1$个正整数,第$i$个数为$f_{i+1}$. 接下来一行$n$个数,若第$i$个数为$0$则表示林先森希望$i$号点 ...

  6. HDU4623 CRIME 【状压DP】【同类项合并】

    题目大意: 求相邻元素互质的排列个数. 题目分析: 由于互质只与质因数有关,所以我们对于质因数种类相同的数合并为一类,特殊的,1,17,19,23是一类,因为没有数与他们不互质. 那么我们做各个位进制 ...

  7. 6.28 NOI模拟赛 好题 状压dp 随机化

    算是一道比较新颖的题目 尽管好像是两年前的省选模拟赛题目.. 对于20%的分数 可以进行爆搜,对于另外20%的数据 因为k很小所以考虑上状压dp. 观察最后答案是一个连通块 从而可以发现这个连通块必然 ...

  8. 【62测试】【状压dp】【dfs序】【线段树】

    第一题: 给出一个长度不超过100只包含'B'和'R'的字符串,将其无限重复下去. 比如,BBRB则会形成 BBRBBBRBBBRB 现在给出一个区间[l,r]询问该区间内有多少个字符'B'(区间下标 ...

  9. 2018.10.17 NOIP模拟 管道(状压dp)

    传送门 状压dp好题. 怎么今天道道题都有点东西啊 对于今天题目神仙出题人先膜为上策:%%%%DzYoAk_UoI%%%% 设f[i][j]f[i][j]f[i][j]表示选取点的状态集合为iii,当 ...

随机推荐

  1. Vue.js官方文档学习笔记(一)起步篇

    Vue.js起步 Vue.js介绍 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库 ...

  2. linux DTS介绍

    一. 设备树的由来 1.1. 什么是设备树 1.1.1. Device Tree 可以描述的信息包括CPU的数量和类别,内存基地址和大小,总线和桥,外设连接,中断控制器和中断使用情况,Clock控制器 ...

  3. Codeforces6E_Exposition

    题意 给定一个序列,求有多少个最长连续子序列满足最大值减最小值之差不超过\(k\). 分析 跟序列最大值最小值有关的可以想到单调栈,先预处理出每个数作为最大值能延伸的区间,然后枚举每个数作为最大值. ...

  4. homebrew学习(四)之取消homebrew自动更新

    homebrew自动更新 使用brew install /brew cask install安装软件总是先updating HomeBrew…,速度很慢 取消homebrew自动更新 方法一:使用命令 ...

  5. js事件冒泡、阻止事件冒泡以及阻止默认行为

    事件冒泡 当事件发生后,这个事件就要开始传播(从里到外或者从外向里).为什么要传播呢?因为事件源本身(可能)并没有处理事件的能力,即处理事件的函数(方法)并未绑定在该事件源上.例如我们点击一个按钮时, ...

  6. 一、bif

    缩进是python的灵魂,缩进可以使python的代码整洁,有层次. python是脚本语言,就是为了简单方便以辅助科学运算,因此python有许多bif,build in function 全部都是 ...

  7. PHP出现502解决方案

    nginx 出现 502 有很多原因,但大部分原因可以归结为资源数量不够用,也就是说后端 php-fpm 处 理有问题,nginx 将正确的客户端请求发给了后端的 php-fpm 进程,但是因为 ph ...

  8. AIX中的服务管理

    1.SRC AIX系统使用资源控制器(SRC,system   resource  controller),控制各种服务子系统,包括启动,停止进程,搜集进程状态信息等.   AIX系统中服务有子系统组 ...

  9. 006-saltstack之远程执行

    1.目标 2.执行模块 3.返回 salt ‘*’ cmd.run ‘uptime’ 命令 目标 执行模块 执行模块参数 1.SlatStack远程执行–目标 执行目标:https://docs.sa ...

  10. 登陆Oracle的管理员登陆

    任务栏:开始——运行,CMD 超级管理员进入系统:conn sys/oracle@prod as sysdba; 修改的代码:alter user username identified by use ...