20251019状压DP总结

状压DP是啥呀?

废话,状压DP不就是状态压缩动态规划吗?

有时,仅仅只是有时,题目会让你求关于几个数从一个状态到另一个状态相关问题,那么弄一个dp22222......dp22222......dp22222......的数组显然是不现实的,所以状压DP由此诞生。

这几个数的状态可以看作一个二进制数,每一个数的状态随之对应二进制数的每一个数位,那么每一种这几个数的不同状态组合随之对应一个二进制数。

例题 洛谷 P2622 关灯问题 II

显然,这题bfs就能水过,但是有关状态压缩,所以值得一讲。

首先题目告诉我们有n盏灯,每盏灯可以是开或者关,有几个按钮,每个按钮按下之后可以使每盏灯开或者关,求最开始每盏灯都是开的,最少按几次按钮才能使所有等关上,如果无法实现就输出-1。

在这里介绍几个二进制状态转换的位运算操作:

  1. (n>>k)(n>>k)(n>>k)&111 取出二进制下n的第k位(从右往左)

  2. nnn&((1<<k)−1)((1<<k)-1)((1<<k)−1) 取出二进制下n的右k位

  3. nnn^(1<<k)(1<<k)(1<<k) 将二进制下n的第k位取反

  4. nnn|(1<<k)(1<<k)(1<<k) 将二进制下n的第k位赋值1

  5. nnn&(((~(1<<k))(1<<k))(1<<k)) 将二进制下n的第k位赋值0

相信聪明的你根据上面的提示以及下面的代码一定能AC这道题!

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int a[105][15],n,m;
struct node{
    int x,dep;//状态及步数
};
queue<node> q;
bool vis[2005];//每种状态是否出现过
void bfs(){
    q.push({(1<<n)-1,0});//最开始所有灯都是开的
    while(!q.empty()){
        node d=q.front();
        q.pop();
        if(d.x==0){//如果所有灯都关了
            cout<<d.dep;
            exit(0);//结束程序
        }
        for(int i=1;i<=m;i++){//试每一盏灯
            int f=d.x;//暂时存着
            for(int j=1;j<=n;j++){
                if(a[i][j]==1&&(f&(1<<(j-1)))){//如果这个开关要把这盏灯给关掉并且第i盏灯是开着的
                    f^=(1<<(j-1));//把这盏灯关掉
                }
                if(a[i][j]==-1&&!(f&(1<<(j-1)))){//如果这个开关要把这盏灯给打开并且第i盏灯是关着的
                    f|=(1<<(j-1));//把这盏灯打开
                }
            }
            if(!vis[f]){//如果这个状态没出现过
                q.push({f,d.dep+1});//推入队列
                vis[f]=1;//现在出现过了
            }
        }
    }
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            cin>>a[i][j];
        }
    }
    bfs();
    cout<<-1;//无解输出-1
    return 0;
}

我之前好像写过耶?

相关推荐
HugoStudio_SWAN2 小时前
洛谷 P1420 / P1179 / B4262 最长连号、数字统计与词频统计——统计的三种面孔
c++·学习·程序人生·算法
raindayinrain3 小时前
c++并发
c++
j7~3 小时前
【C++】智能指针的使用及其原理--详解
c++·c++11·内存泄漏·智能指针·raii·boost智能指针
Persistent的粽子!4 小时前
C++:类与对象(一)
开发语言·c++·经验分享·笔记
库玛西5 小时前
深入浅出Linux select网络模型:从底层位图原理到C++面向对象高级封装
linux·服务器·网络·c++·ubuntu
2402_882893865 小时前
深入浅出 unordered_map 与 unordered_set——从使用到底层差异
c++·哈希·unordered_map·unordered_set
今天要早睡_5 小时前
C++ 核心语法速过:命名空间、引用、函数重载与 nullptr 深度解析
android·java·c++
汉克老师6 小时前
CSP-J 初赛(以满分为目标):第二十七课 《图的遍历——BFS广度优先搜索——像“水波纹”一样,一层一层地搜索》
c++·csp-j·小学生·学c++编程
闻缺陷则喜何志丹6 小时前
【动态规划】P3609 [USACO17JAN] Hoof, Paper, Scissor G
c++·算法·动态规划·洛谷
汉克老师6 小时前
CSP-J 初赛(以满分为目标):第二十六课 《图的遍历——DFS深度优先搜索——从“树的先序遍历”走进真正的图世界》
c++·csp-j·小学生·学c++编程