nuo0930 @ 2020-06-21 10:16:53
蒟蒻初学状压dp,样例都没有过
#include<iostream>
using namespace std;
int tot(int x) {
int ans=0;
while(x&1) {
ans++;
x>>=1;
}
return ans;
}
int dp[4][61][61];
int main() {
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int s[61];
int t[61];
int n,m;
cin>>n>>m;
int cnt=0;
for(int i=0; i<1<<m; i++)
if(!(i&(i<<1))&&!(i&(i<<2))) {
s[++cnt]=i;
t[cnt]=tot(i);
}
int a[110]= {0};
char str[11];
for(int i=0; i<n; i++) {
cin>>str;
for(int j=m-1; j>=0; j--)
if(str[j]=='H')
a[i]|=(1<<i);
}
for(int i=1; i<=cnt; i++)
dp[1][i][1]=t[i];
for(int i=1; i<=cnt; i++)
for(int j=1; j<=cnt; j++)
dp[2][i][j]=max(dp[2][i][j],dp[1][j][1]+t[i]);
for(int i=3; i<=100; i++)
for(int j=1; j<=cnt; j++)
if(!(s[j]&a[i]))
for(int k=1; k<=cnt; k++)
if(!((s[k]&s[j])||(s[k]&a[i-1])))
for(int lk=1; lk<=cnt; lk++)
if(!((s[lk]&s[k])||(s[lk]&s[j])||(s[lk]&a[i-2])))
dp[i%3+1][j][k]=max(dp[i%3+1][j][k],dp[(i-1)%3+1][k][lk]+t[j]);
int ans=0;
for(int i=1; i<=cnt; i++)
for(int j=1; j<=cnt; j++)
ans=max(ans,dp[n%3+1][i][j]);
cout<<ans;
return 0;
}
by nuo0930 @ 2020-06-21 10:18:19
顺便说一句,之所以记录里没有我,是因为我的大号被禁言了,没法发帖,所以用小号发贴
by Andy_chen @ 2020-06-21 10:20:27
%%%
by _5011_ @ 2020-06-21 10:23:06
@哪吒三太子 滚动数组错了。。
如果这么编号应该是 dp[(i-1)%3+1][j][k]
by nuo0930 @ 2020-06-21 10:25:59
@Zephyr_ 好像不是
by nuo0930 @ 2020-06-21 10:26:40
还是输出32
by _5011_ @ 2020-06-21 10:30:17
转移条件也有问题吧。。
不是还得考虑横向的吗。。
by nuo0930 @ 2020-06-21 10:31:10
@Zephyr_ 预处理已经考虑了
by _5011_ @ 2020-06-21 10:34:56
if(str[j]=='H')
a[i]|=(1<<i);
不是 1 << j
吗。。
by _5011_ @ 2020-06-21 10:35:30
这个tot函数也错了吧。。。
by nuo0930 @ 2020-06-21 10:36:42
@Zephyr_ 偶谢谢