首页 > 其他分享 >Acwing 291. 蒙德里安的梦想

Acwing 291. 蒙德里安的梦想

时间:2023-03-16 23:46:36浏览次数:52  
标签:状态 cnt 蒙德里安 奇数 int 291 方格 include Acwing

 

状态压缩DP

当把所有横向格子放完后,纵向方格的排放方案只有一种。因此整个划分方案数与横着摆放方格的方案数相同。

f[i, j]表示,目前摆放第i列,j是二进制数状态是整数,看成二进制数,位上的0或1代表不同的情况,这是状态压缩的核心),如果有n行,则j=1~2n-1,表示存储本行在第i-1列伸出横向1x2小方格的情况。

更新的条件(k是上一个状态的j):

  1. 可以从第i-2列伸到第i-1列的行与从第i-1列伸到第i列的行不能重复。即 j&k == 0

  2. 第i-1列所有剩余的连续的空白格子一定要是偶数。即j | k 不存在连续奇数个0. (可以先预处理)

转移的公式:f[i, j] = f[i - 1, k].

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const int N = 12, M = 1 << N;  //N是i的状态,M是j的状态
 7 int n, m; //矩形的行数和列数
 8 long long f[N][M];
 9 bool st[M]; //存储能存在连续奇数个0的状态 
10 
11 int main(){
12     int n, m;
13     while(cin >> n >> m, n || m){
14         memset(f, 0, sizeof f);
15         //预处理是否所有状态不能存在连续奇数个0
16         for(int i = 0; i < 1 << n;i ++ ){
17             st[i] = true;
18             int cnt = 0;//当前连续0的个数
19             for(int j = 0; j < n; j ++ )
20             {
21                 if(i >> j & 1)//当前这一位是1,上一段0已经截止了
22                 {
23                     if(cnt & 1) st[i] = false;//连续的0是否有奇数个,有奇数个则第i个状态不合法
24                     cnt = 0;
25                 }
26                 else cnt ++ ;
27             }
28             if(cnt & 1) st[i] = false; // 判断最后一段0的个数,要是奇数
29         }
30 
31         f[0][0] = 1; 
32         
33         for(int i = 1;i <= m; i ++ )
34             for(int j = 0; j < 1 << n; j ++ )
35                 for(int k = 0; k < 1 << n; k ++ )//枚举第i-1列的所有状态
36                     if((j & k) == 0 && st[j | k])
37                         f[i][j] += f[i - 1][k];
38         
39         cout << f[m][0] << endl;//最后一列是m-1列,当m列没有捅出来任何方块的时候才是合理方案
40     }
41     return 0;
42 }

 

标签:状态,cnt,蒙德里安,奇数,int,291,方格,include,Acwing
From: https://www.cnblogs.com/luxiayuai/p/17225095.html

相关文章

  • 「AcWing学习记录」拓扑排序
    AcWing848.有向图的拓扑序列原题链接图的拓扑序列是针对有向图来说的,无向图是没有拓扑序列的。可以证明,有向无环图一定存在一个拓扑序列,所以有向无环图也被称为拓扑图......
  • 「AcWing学习记录」DFS
    AcWing842.排列数字原题链接#include<iostream>usingnamespacestd;constintN=10;intn;intpath[N];boolst[N];voiddfs(intu){if(u==n)......
  • AcWing100 -- 差分 & 贪心
    1.题目描述题目给定我们一个数组,我们每次可以对数组的一段区间加一或者减一,问我们,使得序列所有数字相等的最少操作次数以及方案个数2.思路很容易想到差分,将题目转......
  • AcWing3305 -- 建图
    1.题目描述给定我们一些初始作物,和作物之间杂交的规则(作物\(a\)和作物\(b\)杂交产生种子\(c\),花费作物\(a\)和作物\(b\)成熟时间的最大值),让我们求,某个作物\(T......
  • AcWing 第 93 场周赛 4868. 数字替换(dfs+剪枝)
    https://www.acwing.com/problem/content/4871/题目大意:给定两个整数n,x。(x为原始数据,n为需要我们把x变成的位数)可以对x进行任意次以下操作:选择x的一位数字y,将x替......
  • AcWing 第 94 场周赛 A B(最短路dij) C(最短路floyed)
    https://www.acwing.com/activity/content/competition/problem_list/2961/AcWing4870.装物品水题#include<bits/stdc++.h>usingnamespacestd;typedeflonglon......
  • AcWing 199. 余数之和 题解
    做了一下午……题解都看不懂,最后自己比比划划弄懂了。题意:给出\(n,k\),求\(\sum\limits_{i=1}^nk\modi\)。首先取模形式十分不好处理,所以我们可以根据取模运算定义做......
  • AcWing94场周赛复盘
    快速手速题不能犹豫已知,每个背包最多可以装件物品。请你计算,要装下件物品最少需要多少个背包。输入格式一个整数。输出格式一个整数,表示所需背包的最少数量。数据范围......
  • AcWing 165. 小猫爬山(dfs)
    https://www.acwing.com/problem/content/167/一共N只小猫,每个缆车最大承重量为W。N只小猫的重量分别是C1、C2……CN。当然,每辆缆车上的小猫的重量之和不能超过W。......
  • Atcoder-ABC291 "Teleporter and Closed off" 动态DP版
    题目地址题意:在一个DAG图中,点i只有最多m条出边连向i+1~i+m(m<=10),边权均为1。对于\(k\in[2,n-1]\),依次输出当点k被删除时1到n的最短路。分析:标准做法无非就是预......