社区讨论

求问玄关

P2704[NOI2001] 炮兵阵地参与者 7已保存回复 15

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
14 条
当前快照
1 份
快照标识符
@mj8ph2ds
此快照首次捕获于
2025/12/16 22:56
2 个月前
此快照最后确认于
2025/12/19 23:00
2 个月前
查看原帖
先贴代码:
CPP
#include <bits/stdc++.h>

using namespace std;

int n,m,can[110][4200],num[110],maxs[110],f[110][2100][2100],ans,cnt[2100];
char a[110][7 + 8];

int main(){
	ios::sync_with_stdio(0);cin.tie(0);
	
	cin >> n >> m;
	for(int i = 1;i <= n;i ++)
		for(int j = 1;j <= m;j ++)
			cin >> a[i][j];
	for(int i = 1;i <= n;i ++)
		for(int j = m;j >= 1;j --)
			if(a[i][j] == 'P') maxs[i] += (1 << (m - j)); 
	for(int i = 1;i <= (1 << 10) + 5;i ++){
		int x = 1;
		while(x <= i){
			if(x & i) cnt[i] ++;
			x <<= 1;
		}
	}
	
	for(int i = 1;i <= n;i ++){
		for(int j = maxs[i];;j = maxs[i] & (j - 1)){
			if(!((j << 2) & j) && !((j << 1) & j)) can[i][++ num[i]] = j;
			if(!j) break;
		}
	}
	
	for(int i = 1;i <= n;i ++){
		for(int j = 1;j <= num[i];j ++){
			int state = can[i][j];
			if(i == 1){
				f[i][state][0] = max(f[i][state][0],cnt[state]);
				continue;
			}
			for(int k = 1;k <= num[i - 1];k ++){ //枚举上一行
				int lst_state = can[i - 1][k];
				if(i > 1 && (state & lst_state)) continue;
				if(i == 2){
					f[i][state][lst_state] = max(f[i][state][lst_state],cnt[state] + cnt[lst_state]);
					continue;
				}
				for(int o = 1;o <= num[i - 2];o ++){
					int lst_bf_state = can[i - 2][o];
					if(i > 2 && (state & lst_bf_state)) continue;
					if(i > 2 && (lst_state & lst_bf_state)) continue;
					
					f[i][state][lst_state] = max(f[i - 1][lst_state][lst_bf_state] + cnt[state],f[i][state][lst_state]);
				}
			}
		}
	}
	
	for(int i = 0;i <= (1 << 10) + 5;i ++){
		for(int j = 0;j <= (1 << 10) + 5;j ++){
			ans = max(ans,f[n][i][j]);
		}
	}
	
	cout << ans;
}
代码中定义了一个很大的数组 f[110][2100][2100],按理来说它占用了 110×2100×2100×4÷1024÷10241.94GB110 \times 2100 \times 2100 \times 4 \div 1024 \div 1024 \approx 1.94 GB 很明显会爆空间,但是交上去并不会,甚至最多只用了 54MB54MB 的空间。
提交记录:https://www.luogu.com.cn/record/253570956
我看到很多题解都用了滚动数组优化,所以说是我的代码有误,还是计算占用空间的方法错了,亦或说这道题使用滚动数组优化是不必要的?

回复

15 条回复,欢迎继续交流。

正在加载回复...