关闭

bzoj 1151: [CTSC2007]动物园zoo 状压dp

标签: 动态规划状压dp
677人阅读 评论(0) 收藏 举报
分类:

       动态规划水题。。

       令f[i][j]表示考虑第1~i个位置,i~i+4位置上面移走或者不移走的状态为j时的最优解。预处理g[i][j]表示在第i位状态为j时的收益,这样就可以O(1)转移了。

       由于题目是环,因此要求首尾的部分状态要重叠;枚举前4位固定不变的状态在进行dp。时间复杂度O(2^4*N*2^5)=O(2^9N)。

       (随手写一发就rk2了什么鬼。。。)

AC代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int n,m,a[50005],f[10005][32],g[10005][32]; bool ok[50005][32];
const int bin[5]={1,2,4,8,16};
int read(){
	int x=0; char cr=getchar();
	while (cr<'0' || cr>'9') cr=getchar();
	while (cr>='0' && cr<='9'){ x=x*10+cr-'0'; cr=getchar(); }
	return x;
}
int main(){
	n=read(); m=read(); int i,j,k,x,y;
	for (i=1; i<=m; i++){
		a[i]=read();
		j=read(); k=read(); x=y=0;
		while (j--) x|=bin[(read()+n-a[i])%n];
		while(k--) y|=bin[(read()+n-a[i])%n];
		for (j=0; j<32; j++)
			if ((j&x) || ((31^j)&y)){ ok[i][j]=1; g[a[i]][j]++; }
	}
	int ans=0;
	for (i=0; i<16; i++){
		memset(f[0],200,sizeof(f[0]));
		f[0][i<<1]=0;
		for (j=1; j<=n; j++)
			for (k=0; k<32; k++) f[j][k]=max(f[j-1][(k&15)<<1],f[j-1][(k&15)<<1|1])+g[j][k];
		ans=max(ans,max(f[n][i<<1],f[n][i<<1|1]));
	}
	printf("%d\n",ans);
	return 0;
}


by lych

2016.6.1

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:258347次
    • 积分:6586
    • 等级:
    • 排名:第4001名
    • 原创:401篇
    • 转载:0篇
    • 译文:0篇
    • 评论:98条
    文章分类
    最新评论