2013 ACM-ICPC亚洲区域赛南京站C题 题解 轮廓线DP

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4804

题目大意

给你一个 \(n \times m\) 的矩形区域。你需要用 \(1 \times 1\) 和 \(1 \times 2\) 的砖块铺满这个区域,且满足如下要求:

  1. 所有的砖块可以竖着放或横着放;
  2. 砖角要放在格点上;
  3. \(1 \times 1\) 的砖不能少于 \(C\) 块也不能多于 \(D\) 块, \(1 \times 2\) 的砖没有数量限制。
  4. 有些方格在一开始就已经被填充了,这些方格不能被任何砖块覆盖。(在输入里用 0 表示这样的方格,用 1 表示普通方格)

请问有多少种满足上述规则的方案可以将矩形区域铺满?

解题思路

轮廓线动态规划,首先将状态压缩,1 表示这个格子现在被覆盖了, 0 表示没有被覆盖,这样可以把当前考虑的轮廓线上的 \(m\) 列的情况压缩成一个整数,然后按照这一回放什么砖、怎么放进行转移。

状态 \(f[now][s][k]\) 表示:当前位置(\(now\) 能够描绘出行号和列号,以滚动数组实现),以当前位置结尾的不确定状态为 \(s\) ,并且已经放了 \(k\) 个 \(1 \times 1\) 的砖块的方案总数。

进行完轮廓线DP后,答案即为 \(\sum_{i=C}^{D} f[now][(1<<m)-1][i]\) 。

实现代码如下:

#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1000000007LL;
int n, m, C, D;
long long f[2][1<<11][22];
char maze[101][11];
int main() {
    while (~scanf("%d%d%d%d", &n, &m, &C, &D)) {
        for (int i = 0; i < n; i ++) scanf("%s", maze[i]);
        memset(f[0], 0, sizeof(f[0]));
        int now = 0;
        f[0][(1<<m)-1][0] = 1;
        for (int i = 0; i < n; i ++) {  // 遍历行号i
            for (int j = 0; j < m; j ++) {  // 遍历列号j
                now = now ^ 1;
                memset(f[now], 0, sizeof(f[now]));
                for (int k = 0; k <= D; k ++) {     // 遍历放置前已放置1x1砖块个数k
                    for (int s = 0; s < (1<<m); s ++) { // 遍历放置前不确定点状态
                        int s2, k2;
                        /** 当前格子不能放 */
                        if (maze[i][j] == '0') {
                            if (s & (1<<(m-1))) {   // 最前面格子也放了
                                s2 = (s<<1)^1, k2 = k;
                                s2 &= (1<<m)-1;
                                f[now][s2][k2] += f[now^1][s][k];
                                f[now][s2][k2] %= MOD;
                            }
                        }
                        /** 当前格子可以放 */
                        else {  // maze[i][j] == '1'
                            /** 情况1:当前格子不放 */
                            if (s & (1<<(m-1))) {
                                s2 = (s<<1), k2 = k;
                                s2 &= (1<<m)-1;
                                f[now][s2][k2] += f[now^1][s][k];
                                f[now][s2][k2] %= MOD;
                            }
                            /** 情况2:当前格子放一个竖着2x1的砖块 */
                            if (i > 0 && !(s & (1<<(m-1)))) {
                                s2 = (s<<1)^1, k2 = k;
                                s2 &= (1<<m)-1;
                                f[now][s2][k2] += f[now^1][s][k];
                                f[now][s2][k2] %= MOD;
                            }
                            /** 情况3:当前格子放一个横着1x2的砖块 */
                            if (j > 0 && !(s & 1) && (s & (1<<(m-1)))) {
                                s2 = (s<<1)^3, k2 = k;
                                s2 &= (1<<m)-1;
                                f[now][s2][k2] += f[now^1][s][k];
                                f[now][s2][k2] %= MOD;
                            }
                            /** 情况4:当前格子放一个1x1的砖块 */
                            if ( k < D && (s & (1<<(m-1))) ) {
                                s2 = (s<<1)^1, k2 = k+1;
                                s2 &= (1<<m)-1;
                                f[now][s2][k2] += f[now^1][s][k];
                                f[now][s2][k2] %= MOD;
                            }
                        }
                    }
                }
            }
        }
        long long ans = 0;
        for (int i = C; i <= D; i ++) {
            ans = (ans + f[now][(1<<m)-1][i]) % MOD;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/quanjun/p/11962036.html

时间: 2024-10-25 08:03:50

2013 ACM-ICPC亚洲区域赛南京站C题 题解 轮廓线DP的相关文章

2018ACM-ICPC亚洲区域赛南京站I题Magic Potion(网络流)

http://codeforces.com/gym/101981/attachments 题意:有n个英雄,m个敌人,k瓶药剂,给出每个英雄可以消灭的敌人的编号.每个英雄只能消灭一个敌人,但每个英雄只能消灭一个敌人.现在有药剂,英雄喝了之后可以多消灭一个敌人,但每个英雄只能喝一瓶,问最多能消灭多少个敌人. 下午在实验室队内自己开训练,和JC大佬那队一起开的,当时JC大佬他们队开的J题,没有看I题,当我们队AC之后JC大佬才看了I题,听到他们说,这题就差直接把网络流三个字写在题目里了.确实非常明显

2015 ACM / ICPC 亚洲区域赛总结(长春站&amp;&amp;北京站)

队名:Unlimited Code Works(无尽编码)  队员:Wu.Wang.Zhou 先说一下队伍阵容:Wu是大三学长:Wang高中noip省一:我最渣,去年来大学开始学的a+b,参加今年区域赛之前只学了大部分图论内容,以及一些数据结构.动态规划等等,但是还不能熟练运用... ... 先从长春站说起吧... ... 长春站是我加入ACM以来参加的第一场ICPC,因此无比的激动!从杭州出发,乘了整整24小时的火车,终于到达了长春:第一次到大东北,沿途的风景与南方有很大差异,体会到了东北的寒

2014ACM/ICPC亚洲区域赛牡丹江站总结

我在集训队里面也就一般水平,这次学校史无前例的拿到了8个名额,由于大三的只有两个队伍,所以我们13及能分到名额,由于13及人数很多,组长就按照谁在oj上面a的题多就让谁去,我和tyh,sxk,doubleq幸运的在大二就有机会参加亚洲现场赛,非常激动.牡丹江赛区是我和sxk和doubleq组成rainbow战队,我们对这次区域赛其实就是去张张见识,增加大赛经验(外加公费旅游2333),可是当我们真正来到赛场的时候不知道为上面我非常渴望拿一块牌子.第一天热身赛,double迅速切下水题,我一直再弄

2014ACM/ICPC亚洲区域赛牡丹江站汇总

球队内线我也总水平,这所学校得到了前所未有的8地方,因为只有两个少年队.因此,我们13并且可以被分配到的地方,因为13和非常大的数目.据领队谁oj在之上a谁去让更多的冠军.我和tyh,sxk,doubleq运的在大二就有机会參加亚洲现场赛,非常激动.牡丹江赛区是我和sxk和doubleq组成rainbow战队,我们对这次区域赛事实上就是去张张见识,添加大赛经验(外加公费旅游2333),但是当我们真正来到赛场的时候不知道为上面我非常渴望拿一块牌子. 第一天热身赛,double迅速切下水题.我一直再

2014ACM/ICPC亚洲区域赛牡丹江站现场赛-A ( ZOJ 3819 ) Average Score

Average Score Time Limit: 2 Seconds      Memory Limit: 65536 KB Bob is a freshman in Marjar University. He is clever and diligent. However, he is not good at math, especially in Mathematical Analysis. After a mid-term exam, Bob was anxious about his

ICPC2019 亚洲区域赛 南京站

蒟蒻终于打完了人生的第一场ICPC了. 终榜去星后rank36,AG,和AU差几十罚时了. 虽有遗憾但总体也是正常发挥了. 不愿再去对比赛做什么回顾,甚至很不愿去想.很多题已经在能力之外,即便是平常熟练的东西码量也些大就跪了吧. 希望能不忘初心 希望能向第一次走进这个世界那样走下去 希望能守护这份热忱与挚爱 希望我们能一直走下去 原文地址:https://www.cnblogs.com/mollnn/p/11749139.html

2014ACM/ICPC亚洲区域赛牡丹江站现场赛-I ( ZOJ 3827 ) Information Entropy

Information Entropy Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge Information Theory is one of the most popular courses in Marjar University. In this course, there is an important chapter about information entropy. Entropy is t

2014ACM/ICPC亚洲区域赛牡丹江站D和K题

Known Notation Time Limit: 2 Seconds      Memory Limit: 131072 KB Do you know reverse Polish notation (RPN)? It is a known notation in the area of mathematics and computer science. It is also known as postfix notation since every operator in an expre

2014ACM/ICPC亚洲区域赛牡丹江站现场赛-K ( ZOJ 3829 ) Known Notation

Known Notation Time Limit: 2 Seconds      Memory Limit: 65536 KB Do you know reverse Polish notation (RPN)? It is a known notation in the area of mathematics and computer science. It is also known as postfix notation since every operator in an expres