炮兵阵地
发现好像只记一行没什么太大的用了。怎么办……
一行不行记两行呗!m=10的情况也只有60种可行方案,空间大大的有。
注意不是累加是取max……
看代码:
#include<bits/stdc++.h> using namespace std; int f[105][65][65]; int can[65],num[65],pd[105]; int n,m,bai[13],cnt,ans; void dfs(int x){ if(x==m+1){ cnt++; for(int i=1;i<=m;i++) can[cnt]=2*can[cnt]+bai[i]; for(int i=1;i<=m;i++) num[cnt]+=bai[i]; return; } bai[x]=0; dfs(x+1); if(bai[x-1]==0&&(x==1||bai[x-2]==0)) bai[x]=1,dfs(x+1); } int main(){ cin>>n>>m; string s; for(int i=1;i<=n;i++){ cin>>s; for(int j=1;j<=m;j++) pd[i]=2*pd[i]+1-(s[j-1]=='P'); } //for(int i=1;i<=n;i++) // printf("%d\n",pd[i]); dfs(1); //printf("%d\n",cnt); //for(int i=1;i<=cnt;i++) // printf("%d\n",can[i]); for(int i=1;i<=cnt;i++) if(!(pd[1]&can[i]))f[1][i][0]=num[i]; for(int i=1;i<=cnt;i++) if(!(pd[2]&can[i])) for(int j=1;j<=cnt;j++) if(!(pd[1]&can[j])) if(!(can[i]&can[j])) f[2][i][j]=max(f[2][i][j],f[1][j][0]+num[i]); for(int i=3;i<=n;i++) for(int j=1;j<=cnt;j++) if(!(pd[i]&can[j])) for(int k=1;k<=cnt;k++) if(!(pd[i-1]&can[k])) for(int p=1;p<=cnt;p++) if(!(pd[i-2]&can[p])) if(!(can[j]&can[k])&&!(can[k]&can[p])&&!(can[j]&can[p])) f[i][j][k]=max(f[i][j][k],f[i-1][k][p]+num[j]); for(int i=1;i<=cnt;i++) if(!(pd[n]&can[i])) for(int j=1;j<=cnt;j++) if(!(pd[n-1]&can[j])) if(!(can[i]&can[j])) ans=max(ans,f[n][i][j]); printf("%d\n",ans); return 0; }
深深地感到自己的弱小。