P2704 感觉思路错了
查看原帖
P2704 感觉思路错了
420102
phmaprostrate楼主2021/8/20 21:33

没用滚动数组 因为样例没过 思路是 预处理 2行。然后枚举前两行。

#include<iostream>
using namespace std;
const int N = 102,M = 11,S = 1 << M;
int s[N][M];
int so[S];
int Map[N];
bool can[S];
bool check(int ss){
	if(((ss << 1) & ss) == 0 &&((ss << 2) & ss) == 0) return true;
	else return false;
}
int n,m;
int dp[N][S][S];
int main(){
	cin >> n >>m;
	for(int i = 1;i <= n;i++)
	 for(int j = 1;j <= m;j++){
	 	char x; 
	 	cin >> x;
	 	s[i][j] = (x == 'P');
	 	Map[i] = (Map[i] << 1) + (x == 'P');
	 }
	 int statem = 1 << m - 1;
	 for(int i = 0;i <= statem;i++){
	 	int x = i;//处理每个状态的炮兵
	 	while(x){
	 	so[i]++;
		 x = (x - 1) & x;	
		 }
	 }
	 for(int i = 0;i <= statem;i++){
	 	if(check(i)) can[i] = true;
	 }
     //第一行
	 for(int i = 0;i <= statem;i++){
	 	if(can[i] && ((Map[1] & i) == i)) dp[1][0][i] = so[i];
	 }
     // 第2行
	 for(int i = 0;i <= statem;i++){
	 	if(can[i] && ((Map[1] & i) == i)){
	 		for(int j = 0;j <= statem;j++){
	 			if(!can[j] || (i & j) || ((Map[2] & j)!=j)) continue;
	 			dp[2][i][j] = dp[1][0][i] + so[j];
			 }
		 }
	 }
	 for(int i = 3;i <= n;i++)
	  for(int j = 0;j <= statem;j++){
	  	if(can[j] && ((Map[j] & j) == j)){
	  		for(int s = 0;s <= statem;s++){
	  			if(!can[s] ||(s & j) || ((Map[i - 1] & s) != s)) continue;
	  			for(int u = 0;u <= statem;u++){
	  				if(!can[u] || (u & s) || ((Map[i - 2] & u) != u)) continue;
	  				dp[i][s][j] = max(dp[i][s][j],dp[i - 1][u][s] + so[j]);
				  }
			  }
		  }
	  }
	  int ans = 0;
	  for(int u = 0;u <= statem;u++)
	   for(int j = 0;j <= statem;j++){
	   	ans = max(ans,dp[n][u][j]);
	   }
	   cout<<ans;
	return 0;
}
2021/8/20 21:33
加载中...