焚魂 @ 2021-10-21 18:11:42
首先这是我的代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m;
int F[210];
char s;
int f[210][1 << 15];
bool state[1 << 15];
int zt[1 << 15],s0;
int ans;
int ssum[1 << 15];
int Sum(int x) {
int num = 0;
while(x) {
if((x & 1) == 1)
num++;
x >>= 1;
}
return num;
}
int main() {
cin >> n >> m;
// freopen("out.txt","w",stdout);
const int MAXNS = (1 << m);
for(int i = 1;i <= n;i++) {
for(int j = 1;j <= m;j++) {
cin >> s;
if(s == 'P') {
F[i] = (F[i] << 1) + 0;
}
else {
F[i] = (F[i] << 1) + 1;
}
}
}
for(int i = 0;i < MAXNS;i++) {
if(((i & (i >> 1)) == 0) && ((i & (i >> 2)) == 0) && ((i & (i << 1)) == 0) && ((i & (i << 2)) == 0)) {
state[i] = true;
ssum[i] = Sum(i);
}
else
state[i] = false;
}
for(int i = 0;i < MAXNS;i++) {
if(state[i])
zt[++s0] = i;
}
for(int i = 0;i <= MAXNS;i++) {
if(state[i] && (i & F[1]) == 0) {
f[1][i] = ssum[i];
}
}
for(int i = 1;i <= s0;i++) {
for(int j = 1;j <= n;j++) {
if((zt[i] & F[j]) == 0) {
for(int k = 1;k <= s0;k++) {
if((zt[i] & zt[k]) == 0) {
for(int z = 1;z <= s0;z++) {
if(((zt[z] & zt[i]) == 0) && ((zt[z] & zt[k]) == 0)) {
f[j][zt[i]] = max(f[j][zt[i]],f[j-1][zt[k]] + ssum[zt[i]]);
}
}
}
}
}
}
}
for(int i = 1;i <= s0;i++) {
ans = max(ans,f[n][zt[i]]);
}
cout << ans;
return 0;
}
然后这一段:
f[j][zt[i]] = max(f[j][zt[i]],f[j-1][zt[k]] + ssum[zt[i]]);
是由原本这一句:
f[j][zt[i]] = max(f[j][zt[i]],f[j-1][zt[k]] + 1);
改过来的。按照常理来说,加这个状态中1的个数,即这个状态放的炮兵的个数应该是不小于1的,但是这一组数据:this 如果是原本的+1答案是103,改成这样确变成26,变小了蒟蒻就很不理解,有没有大佬帮忙解答一下QAQ