[Cometoj#3 B]棋盘_状压dp

棋盘

题目链接https://cometoj.com/contest/38/problem/B?problem_id=1535

数据范围:略。



题解

因为行数特别小,所以$dp$的时候可以状压起来。

之后就非常傻逼了....

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

#define N 1000010 

using namespace std;

char *p1, *p2, buf[100000];

#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )

int rd() {
    int x = 0, f = 1;
    char c = nc();
    while (c < 48) {
        if (c == ‘-‘)
            f = -1;
        c = nc();
    }
    while (c > 47) {
        x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
    }
    return x * f;
}

int a[N], b[N], f[N][2];

int main() {
    int n = rd();
    for (int i = 1; i <= n; i ++ ) {
        a[i] = rd();
    }
    for (int i = 1; i <= n; i ++ ) {
        b[i] = rd();
    }

    int l = N, r = 1;
    for (int i = 1; i <= n; i ++ ) {
        if (a[i] || b[i]) {
            l = i;
            break;
        }
    }
    for (int i = n; i; i -- ) {
        if (a[i] || b[i]) {
            r = i;
            break;
        }
    }

    for (int i = l; i <= r; i ++ ) {
        f[i][0] = f[i - 1][0] + !a[i];
        f[i][1] = f[i - 1][1] + !b[i];
        f[i][0] = min(f[i][0], f[i][1] + !a[i]);
        f[i][1] = min(f[i][1], f[i][0] + !b[i]);
    }

    cout << min(f[r][0], f[r][1]) << endl ;
    return 0;
}

原文地址:https://www.cnblogs.com/ShuraK/p/11726377.html

时间: 2024-10-09 10:05:47

[Cometoj#3 B]棋盘_状压dp的相关文章

BZOJ_1076_[SCOI2008]奖励关_状压DP

题意: 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物, 每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再吃). 宝物一共有n种,系统每次抛出这n种宝物的概率都相同且相互独立.也就是说,即使前k-1次系统都抛出宝物1( 这种情况是有可能出现的,尽管概率非常小),第k次抛出各个宝物的概率依然均为1/n. 获取第i种宝物将得到Pi 分,但并不是每种宝物都是可以随意获取的.第i种宝物有一个前提宝物集合Si.只

[poj1185]炮兵阵地_状压dp

炮兵阵地 poj-1185 题目大意:给出n列m行,在其中添加炮兵,问最多能加的炮兵数. 注释:n<=100,m<=10.然后只能在平原的地方建立炮兵. 想法:第2到状压dp,++.这题显然是很经典的.设状态dp[i][j][k]表示第i行的状态为j,i-1行的状态为k的最多炮兵数.在转移时,枚举所有的合法炮兵排列(此处的合法数目是根据一行全为平原的时候能放置的合法炮兵数目),然后内层循环枚举dp[i-1]的i-1状态,进行特判更新即可.统计答案时,我们只需对于dp[n]的所有可能状态求最大值

[bzoj3717][PA2014]Pakowanie_动态规划_状压dp

Pakowanie bzoj-3717 PA-2014 题目大意:给你n个物品m个包,物品有体积包有容量,问装下这些物品最少用几个包. 注释:$1\le n\le 24$,$1\le m\le 100$ 想法:以为是什么超级牛逼的背包dp,结果就是状压dp 状态:f[s]表示装s状态的物品需要多少背包,g[s]表示在f[s]的前提下,最大的背包剩余的容量. 转移:直接判断最后一个能不能装下当前物品,转移即可. 还有就是这个题卡常,只能直接用Lowbit枚举1,不能全枚举,会T... ... 最后

[bzoj1879][Sdoi2009]Bill的挑战_动态规划_状压dp

Bill的挑战 bzoj-1879 Sdoi-2009 题目大意: 注释:$1\le t \le 5$,$1\le m \le 15$,$1\le length \le 50$. 想法: 又是一个看数据范围想做法的题,我们想到状压dp. 看了题解... ...网上给的状态是f[len][s]表示长度为len满足状态s的字符串个数. 光看状态... ...可能算重啊?! 其实... ... 状态:dp[len][s]表示长度为len,能且只能满足状态为s的字符串个数. 转移:我们先预处理出g[i]

[LuoguP2157][SDOI2009]学校食堂_状压dp

学校食堂 题目链接:https://www.luogu.org/problem/P2157 数据范围:略. 题解: 发现$B$特别小,很容易想到状压. 即在$dp$的时候弄出来$f_{(i,j,k)}$表示前$i - 1$个都打完了饭,状态$j$也已经打完饭了,当前打饭的是$i$,上一个打饭的是$i+k$这样能存的下. 转移的话需要枚举状态,但是没必要枚举完全因为毕竟是长度只有$7$. 看见了相邻两个人转移的代价之后,以为可以根据位运算能搞出点什么东西发现啥也搞不动. 我们可以适当地省略一些条件

BZOJ 4000: [TJOI2015]棋盘( 状压dp + 矩阵快速幂 )

状压dp, 然后转移都是一样的, 矩阵乘法+快速幂就行啦. O(logN*2^(3m)) --------------------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define b(x) (1 <&l

[ An Ac a Day ^_^ ] POJ 3254 Corn Fields 状压dp

题意: 有一块n*m的土地 0代表不肥沃不可以放牛 1代表肥沃可以放牛 且相邻的草地不能同时放牛 问最多有多少种放牛的方法并对1e8取模 思路: 典型的状压dp 能状态压缩 能状态转移 能状态压缩的题的特点就是只有两种状态 所以用0 1表示两种状态 用位运算判断是否符合条件 然后将前一行的合理状态转移到后一行 最后统计最后一行的状态 dp[i][j]代表第i行以第j种状态放牛时有多少种不同的状态 (c++的语言特性是 封装 继承 多态~) 1 /* ***********************

nyoj1273 河南省第九届省赛_&quot;宣传墙&quot;、状压DP+矩阵幂加速

宣传墙 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 ALPHA 小镇风景美丽,道路整齐,干净,到此旅游的游客特别多.CBA 镇长准备在一条道路南 面 4*N 的墙上做一系列的宣传.为了统一规划,CBA 镇长要求每个宣传栏只能占相邻的两个方格 位置.但这条道路被另一条道路分割成左右两段.CBA 镇长想知道,若每个位置都贴上宣传栏, 左右两段各有有多少种不同的张贴方案. 例如: N=6,M=3, K=2, 左,右边各有 5 种不同的张贴方案 输入 第一行: T 表示

BZOJ_2734_[HNOI2012]集合选数_构造+状压DP

题意:<集合论与图论>这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x 在该子集中,则 2x 和 3x 不能在该子集中.同学们不喜欢这种具有枚举性 质的题目,于是把它变成了以下问题:对于任意一个正整数 n≤100000,如何求出{1, 2,..., n} 的满足上述约束条件的子集的个数(只需输出对 1,000,000,001 取模的结果),现在这个问题就 交给你了. 分析: 我们构造出一个矩阵 1 2^0*3^1 2^0*3^2 2^1*3^