***POJ1185 炮兵阵地 ACM解题报告(状压dp入门题)

这题是个入门的状压dp(虽然对我来说好难啊,坑了一下午终于过了。。。)难得一个中文题,还这么难

注意点挺多的,首先是要开数组记录所有情况,然后记录每种情况的炮兵数,很多处理类似于前一题3254,可以参考,不过这题更难一点,因为需要考虑两行。

所以得开个三维数组记录情况,d[i][j][k],i是当前行数,j是第i行的情况,k是i-1行的情况。

状态转移方程:d[i][j][k]=max(d[i][j][k],d[i-1][k][h]+num[j]),需要注意几个限制state[j]&b[i]==0,state[j]&state[k]==0,state[j]&state[h]==0,边界是d[0][j][k]=num[j]。

其中需要注意的是num数组是记录每种情况有多少个炮兵,就是要记录一个二进制数之中有多少个1,位运算优先级低,一定要加括号(我就是被拿了学长写的代码然后没加括号,看了一下午。。。虽然自己也有个手误。)

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define MAX 105
typedef long long LL;
const double pi=3.141592653589793;
const int INF=1e9;
const double inf=1e20;
const double eps=1e-6;
int top,b[105],d[105][100][100];//第一维是第i行,第二维是第i行的状态,第三维是i-1行的状态,存储的是能有多少个炮兵
int state[100];//记录一行上满足条件的总的情况种类
int num[100];//记录每种情况有多少个炮兵
int n,m;
bool ok(int x){
	if(x&(x<<1)) return false;//相邻2隔内不能有炮兵
	if(x&(x<<2)) return false;
	return true;
}
int bitcount(int x) { 
	return x == 0 ? 0 : bitcount(x/2) + (x&1);//&优先级低,要加括号(ps.被学长阴掉了)
}
void init(){
	int total=(1<>n>>m;
	init();
	memset(b,0,sizeof(b));
	memset(d,-1,sizeof(d));
	for(int i=0;i


你可能感兴趣的:(***POJ1185 炮兵阵地 ACM解题报告(状压dp入门题))