蓝桥杯系列 - 2019国赛 - 矩阵计数

矩阵的每个位置只有两种可能的状态,加上 N, M 的范围这么小,很容易想到要用到二进制,往这个思路想下去就想到了状压 DP。
大致思路如下:

  1. 输入 N, M,矩阵每行的状态就有 numState = 2M 个。
  2. 假设 1 代表题中的 ‘X’,0 代表题中的 ‘O’。可以先从 [0, numState - 1] 里面挑出符合条件的数存进一个数组 stateAllowed,所谓“符合条件”就是这些数的二进制表示没有连续 3 个 1,例如 8 = (1000)2 是符合条件的,而 7 = (0111)2 和 15 = (1111)2 是不符合条件的。
  3. 设置 dp[N][numState][numState],dp[i][j][k] 表示矩阵第 i 行的状态为 j,前一行的状态为 k 时,符合条件的矩阵有多少个。状态转移方程如 Pseudocode1 所示。dp 的初始化稍微有些难想到。我们假设矩阵的行号从 0 开始计数,采用 Pseudocode2 所示的方法对 dp 进行初始化。
""" Pseudocode1 """
for j in stateAllowed:
	for k in stateAllowed:
		for p in stateAllowed:
			if j & k & p == 0:  // 这个判断能保证矩阵在列上不会出现连续的 31
				dp[i][j][k] += dp[i - 1][k][p]
""" Pseudocode2 """
for j in stateAllowed:
	dp[0][j][0] = 1  // dp[0 - 1]并不存在, 也就是矩阵第 0 - 1 行并不存在
					 // 但我们可以假想它存在并且只有状态 0, 以此来对第 0 行进行初始化

时间复杂度为 O(N * 23M)
Python 代码如下:

import sys


N, M = list(map(int, sys.stdin.readline().strip().split()))
numState = 2 ** M

stateAllowed = []
for i in range(numState):
    cnt, flag = 0, False
    temp = i
    while temp:
        if temp & 1:
            cnt += 1
        else:
            cnt = 0
        if cnt >= 3:
            flag = True
            break
        temp >>= 1
    if not flag:
        stateAllowed.append(i)

dp = [[[0 for _ in range(numState)] for __ in range(numState)] for ___ in range(N)]
for i in stateAllowed:
    dp[0][i][0] = 1
for i in range(1, N):
    for j in stateAllowed:
        for k in stateAllowed:
            for p in stateAllowed:
                if j & k & p == 0:
                    dp[i][j][k] += dp[i - 1][k][p]
ans = 0
for i in stateAllowed:
    ans += sum(dp[N - 1][i])
print(ans)

还有一种比较简单的方法,也就是 DFS + 二进制枚举,如果在比赛时想不出状压 DP 就可以用这个方法。具体思路就不写了,挺容易的。不过不推荐 Python 选手用这种方法,因为这种方法时间复杂度为 O(2N*M),在本题不放松时间限制的情况下可能会超时,因为 Python 运行效率比较低。这种方法推荐 C++ 选手使用。

### 如何在 IntelliJ IDEA 中配置和使用 Swagger #### 添加 Maven 依赖 为了使 Swagger 能够工作,在 `pom.xml` 文件中需加入特定的依赖项。这可以通过编辑项目的构建文件来完成: ```xml <dependencies> <!-- swagger2 --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.8.0</version> </dependency> <!-- swagger ui --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.8.0</version> </dependency> </dependencies> ``` 这些依赖会引入必要的库用于生成 API 文档以及提供交互式的 UI 页面[^4]。 #### 创建 Swagger 配置类 接着创建一个新的 Java 类用来初始化并配置 Swagger 实例。通常命名为类似于 `SwaggerConfig.java` 的名称,并放置于合适的位置,比如 `config` 包内: ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; @Configuration public class SwaggerConfig { @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .build(); } private ApiInfo apiInfo(){ return new ApiInfoBuilder().title("API文档").description("").termsOfServiceUrl("") .contact(new Contact("", "", "")) .license("").licenseUrl("").version("1.0") .build(); } } ``` 这段代码定义了一个 Spring Bean 来设置 Swagger 的基本信息和其他选项。 #### 启动应用测试 当上述步骤完成后,启动应用程序即可访问默认路径 `/swagger-ui.html` 查看自动生成的 RESTful 接口文档界面。通过浏览器打开该链接可以浏览到所有已暴露出来的 HTTP 请求方法及其参数说明等信息。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值