zoukankan      html  css  js  c++  java
  • 状压dp

    用dfs,累加答案,或者什么的。他可能还会有一些限制,加点判断就好。

    sgu 131

    #include <stdio.h>
    using namespace std;
    #define LL long long
     
    int n, m, i;
    LL f[10][512];
     
    void dfs(int j, int opt1, int opt2, int u1, int u2)
    {
         if (j == m)
         {
            if (!u1 && !u2) f[i + 1][opt2] += f[i][opt1]; 
            return;
         }
         // Put this block
         if (!u2)
         {
            if (!u1)
            {
               dfs(j+1, opt1<<1, (opt2<<1)+1, 0, 0); // Case 1
               dfs(j+1, opt1<<1, (opt2<<1)+1, 1, 0); // Case 2
               dfs(j+1, opt1<<1, (opt2<<1)+1, 0, 1); // Case 3
            }
            dfs(j+1, (opt1<<1)+1-u1, (opt2<<1)+1, 0, 1); // Case 4
            dfs(j+1, (opt1<<1)+1-u1, (opt2<<1)+1, 1, 1); // Case 5
         }
         // NO put or Already put this block
         if (!u1) dfs(j+1, opt1<<1, (opt2<<1)+u2, 1, 1); // Case 6
         dfs(j+1, (opt1<<1)+1-u1, (opt2<<1)+u2, 0, 0); // Case 7
    }
     
    int main()
    {
        scanf("%d %d", &n, &m);
        if (n < m) { n ^= m; m ^= n; n ^= m; }
        f[0][(1<<m)-1] = 1;
        for (i = 0; i < n; ++i)
            dfs(0, 0, 0, 0, 0);
        printf("%I64d", f[n][(1<<m)-1]);
        return 0;
    }

     sgu 132

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #define INF 16843009
    using namespace std;
    int g[71], Tmi[] = {1, 2, 4, 8, 16, 32, 64, 128};
    int f[2][1 << 8][1 << 8];
    int n, m, x, stI, stJ,ans=INF;
    //状态压缩,0代表不放,1代表放
    //对每一行DFS时填它的上一行
    void dfs (int k, int opt1, int opt2, int cnt) {
           //填完k列后,如果前两行中出现了连续0,退出
        if (k > 0 && (stI & Tmi[k - 1]) == 0 && (opt1 & Tmi[k - 1]) == 0) return;
        if (k > 1 && (opt1 & Tmi[k - 1]) == 0 && (opt1 & Tmi[k - 2]) == 0) return;
        if (k == m) {
            if (f[x ^ 1][stI][stJ] != INF)
                f[x][opt1][opt2] = min (f[x][opt1][opt2], f[x ^ 1][stI][stJ] + cnt);
            return;
        }
        //这一列不填
        dfs (k + 1, opt1, opt2, cnt);
        //填上一行,和当前一行的同一列
        if ( (opt1 & Tmi[k]) == 0 && (opt2 & Tmi[k]) == 0)
            dfs (k + 1, opt1 | Tmi[k], opt2 | Tmi[k], cnt + 1);
           //填上一行的连续两列
        if (k < (m - 1) && (opt1 & Tmi[k]) == 0 && (opt1 & Tmi[k + 1]) == 0)
            dfs (k + 1, opt1 | Tmi[k + 1] | Tmi[k], opt2, cnt + 1);
    }
    int main() {
        scanf ("%d %d", &n, &m);
        char st[71];
        for (int i = 1; i <= n; i++) {
            scanf ("%s", st + 1);
            for (int j = 1; j <= m; j++)
                g[i] = g[i] << 1 | (st[j] == '*');
        }
        memset (f, 1, sizeof f);
        f[1][Tmi[m] - 1][g[1]] = 0;
        for (int k = 1; k <= n; k++) {
            for (int i = 0; i < Tmi[m]; i++)
                for (int j = 0; j < Tmi[m]; j++) {
                    if (f[x ^ 1][i][j] != INF){
                                       stI = i, stJ = j;
                        dfs (0, j, g[k + 1], 0);
                    }
                }
            memset (f[x ^ 1], 1, sizeof f[x ^ 1]);
            x ^= 1;
        }
        x ^= 1;
        for (int i = 0; i < Tmi[m]; i++)
            for (int j = 0; j < Tmi[m]; j++)
                if (f[x][i][j] > 0)     ans = min (ans, f[x][i][j]);
        printf ("%d", ans);
    }
  • 相关阅读:
    自己常用网站记录
    css弹性布局指定显示行数多余文字去掉用省略号代替以及弹性布局中css 卡片阴影效果
    微信小程序页面传参被截取问题
    阴影效果 css3 为什么要加 -moz-box-shadow -webkit-box-shadow -o-box-shadow,直接用box-shadow不是都能识别吗?
    css常用清除浮动方式
    什么是微信小程序云开发 它的作用是什么
    JMeter压测“java.net.SocketException: Socket closed”解决方法
    Jmeter压力测试工具安装及使用教程
    OnActionExecuting和OnActionExecuted执行顺序
    C#循环下载多个文件(把多个文件压缩成一个文件可以一次性下载)
  • 原文地址:https://www.cnblogs.com/Rainb/p/3844837.html
Copyright © 2011-2022 走看看