zoukankan      html  css  js  c++  java
  • 【算法】状态压缩DP

    状态压缩DP是什么?

    答:利用位运算(位运算比加减乘除都快!)来记录状态,并实现动态规划。

    适用于什么问题?

    答:数据规模较小;不能使用简单的算法解决。

    例题:

    题目描述

    糖果店的老板一共有M 种口味的糖果出售。为了方便描述,我们将M种口味编号1~M。
    小明希望能品尝到所有口味的糖果。遗憾的是老板并不单独出售糖果,而是K颗一包整包出售。
    幸好糖果包装上注明了其中K 颗糖果的口味,所以小明可以在买之前就知道每包内的糖果口味。
    给定N 包糖果,请你计算小明最少买几包,就可以品尝到所有口味的糖果。

    输入

    第一行包含三个整数N、M 和K。
    接下来N 行每行K 这整数T1,T2,...,TK,代表一包糖果的口味。
    1<=N<=100,1<=M<=20,1<=K<=20,1<=Ti<=M。

    输出

    一个整数表示答案。如果小明无法品尝所有口味,输出-1。

    样例输入 

    6 5 3
    1 1 2
    1 2 3
    1 1 3
    2 3 5
    5 4 2
    5 1 2

    样例输出

    2

    数据规模不大,很适合用状态压缩DP。

    思路如下:

    用二进制的1和0来表示某类糖果的有无。比如按照上面的样例,总共有5种糖果。第二行1 1 2就是00011,第三行1 2 3就是00111,最后一行5 1 2就是10011...

    然后我们用dp数组在存储这些状态。

    int dp[1<<m];

    将其初始化为-1.每读取一行,就将相对应的元素赋值1,代表买一包就能买到这些种类的糖果。

    AC代码如下:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 int main() {
     5     int n, m, k,s,ss;
     6     cin >> n >> m >> k;
     7     int dp[1 << 20];
     8     int goods[100];
     9     memset(dp, -1, sizeof(dp));
    10     for(int j=0;j<n;j++) {
    11         ss = 0;
    12         for (int i = 0; i < k; i++) {
    13             cin >> s;
    14             ss |= (1 << (s - 1));
    15         }
    16         goods[j] = ss;
    17         dp[ss] = 1;
    18     }
    19     for (int i = 0; i < n; i++) {
    20         for (int j = 0; j < (1 << m); j++) {
    21             if (dp[j] == -1) continue;
    22             if (dp[j | goods[i]] == -1)
    23                 dp[j | goods[i]] = dp[j] + dp[goods[i]];
    24             else
    25                 dp[j | goods[i]] = min(dp[j] + dp[goods[i]], dp[j | goods[i]]);
    26         }
    27     }
    28     cout << dp[(1 << m) - 1];
    29 }

     

  • 相关阅读:
    Linux中OCI开发库的配置
    makefile中的gcc -o $@ $^是什么意思?
    【转】gcc中的-w -W和-Wall选项
    【转】Linux查看系统是32位还是64位方法总结
    【转】gcc命令中参数c和o混合使用的详解
    Python2.7设置在shell脚本中自动补全功能的方法
    Python3设置在shell脚本中自动补全功能的方法
    Pyqt图标下载网站
    如何使QLineEdit禁止编辑
    python偏函数的运用
  • 原文地址:https://www.cnblogs.com/zyyz1126/p/12377491.html
Copyright © 2011-2022 走看看