【luogu题解】P5461 赦免战俘

发布时间 2023-11-22 16:46:30作者: daiyulong

一、题目

  • 现有 \(2^n\times2^n\ (n≤10)\) 名作弊者站成一个正方形方阵等候 kkksc03 的发落。kkksc03 决定赦免一些作弊者。他将正方形矩阵均分为 4 个更小的正方形矩阵,每个更小的矩阵的边长是原矩阵的一半。其中左上角那一个矩阵的所有作弊者都将得到赦免,剩下 3 个小矩阵中,每一个矩阵继续分为 4 个更小的矩阵,然后通过同样的方式赦免作弊者……直到矩阵无法再分下去为止。所有没有被赦免的作弊者都将被处以棕名处罚。

  • 给出 n,请输出每名作弊者的命运,其中 0 代表被赦免,1 代表不被赦免。

二、答案

一道经典的dp题。

在写dp之前,我们需要明确以下几个东西:状态的表示,状态转移方程,边界条件和答案的
表示。

1. 状态的表示

\(dp_{i,j}\) 表示第 i 行 j 列作弊者的命运(其中 0 代表被赦免,1 代表不被赦免)。

2. 状态转移方程

\[\displaystyle\sum_{i=1}^{2^n} \displaystyle\sum_{j=1}^{2^n} dp_{i,j}=dp_{i-1,j}⊕dp_{i-1,j+1} \]

3. 边界条件

\[dp_{\ 0,2^n+1}=1 \]

4. 答案的表示

\[\displaystyle\sum_{i=1}^{2^n} \displaystyle\sum_{j=1}^{2^n} dp_{i,j} \]

三、时间复杂度

整体时间复杂度为 \(O({2^n}^2)\) ,也就是 \(O(2^n\times 2^n)\) ,其中 \(100\%:(n\le10)\)

四、空间复杂度

整体空间复杂度为 \(O({2^n}^2)\) ,也就是 \(O(2^n\times 2^n)\) ,其中 \(100\%:(n\le10)\)

五、AC代码

#include<bits/stdc++.h>
using namespace std;
bool ans[2000][2000];
int main() {
	int n;
	scanf("%d",&n);
	for(int i=1;i<=(1<<n);i++) {
		for(int j=1;j<=(1<<n);j++) {
			ans[i][j]=1;
		}
	}
	ans[0][(1<<n)+1]=1;
	for(int i=1;i<=(1<<n);i++) {
		for(int j=1;j<=(1<<n);j++) {
			ans[i][j]=ans[i-1][j]^ans[i-1][j+1];
		}
	}
	for(int i=1;i<=(1<<n);i++) {
		for(int j=1;j<=(1<<n);j++) {
			printf("%d ",ans[i][j]);
		}
		printf("\n");
	}
	return 0;
}