向前走莫回头❤

【校内互侧】ZYF loves binary (dp)

ZYF loves binary(binary.cpp)
【问题描述】
  ZYF 无聊的时候喜欢研究二进制,她认为二进制的世界中只有三种运算:按位与(and)、按位或(or)和异或(xor)。
  有一天她找来了 n个小伙伴并给他们每人一个权值 ai, 然后她发现第 i个人和第j 个人的友好程度可以表示为ai opt aj,其中 opt是三种运算的一种。
  由于 ZYF忙着刷题所以想让你告诉她,对于从左到右的第2 到n 个人,他们左边与他们友好程度的最大值是多少,还有达到最大值的人数是多少。

【输入格式】
  第一行包含一个整数 n,一个串opt 和一个整数type,分别表示人数,运算类型和数据类型。
  第二行包含 n个整数,表示从左往右第 i个人的权值 ai。

【输出格式】
  如果 type=0,输出 n-1 行,每行一个整数,其中第i 行输出和第i+1 个人友好程度的最大值。
  如果 type=1,输出 n-1 行,每行两个整数,其中第i 行输出和第i+1 个人友好程度的最大值和达到最大值的人数。
【样例输入】
  5 and 1
  3 5 2 7 1
【样例输出】
  1 1
  2 1
  5 1
  1 3
【数据规模及约定】

  对于 100%的数据,0<=ai<65536

  

_______________________________________________________________

【题解】【dp】

【通过看数据范围可知,a[i]最大为2的16次方,所以可以拆分为前八位和后八位来处理】

【f[i][j]表示前八位为i的数和后八位为j的数进行i opt j运算的最大值;g[i][j]表示前八位为i和后八位为j的数进行i opt j运算的最大值的方案数】

【加入一个数x的时候,设前8位为a,后8位为b,枚举j,用所有j opt b更新所有f[a][j]。】
【查询一个数x的时候,枚举所有i,用(i opt a)<<8|f[i][b]更新答案】
【复杂度O(2^8*n)】

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char s[5];
int f[1<<8][1<<8],g[1<<8][1<<8],a[100010];
int n,opt;
inline int check(int x,int y,int j)
{
	if(s[0]=='a') return ((x&j)<<8|f[j][y]);
	if(s[0]=='x') return ((x^j)<<8|f[j][y]);
	if(s[0]=='o') return ((x|j)<<8|f[j][y]);
}
inline int slove(int y,int j)
{
	if(s[0]=='a') return (y&j);
	if(s[0]=='x') return (y^j);
	if(s[0]=='o') return (y|j);
}
int main()
{
	freopen("binary.in","r",stdin);
	freopen("binary.out","w",stdout);
	int i,j;
	scanf("%d%s%d",&n,s,&opt);
	for(i=1;i<=n;++i) scanf("%d",&a[i]);
	memset(f,-1,sizeof(f));
	memset(g,0,sizeof(g));
	for(i=1;i<=n;++i)
	 {
	 	int x=a[i]>>8,y=a[i]%(1<<8);
	 	int maxn=-1,num=0;
	 	if(i!=1)
	 	 {
	 	 	for(j=0;j<=(1<<8)-1;++j)
	 	 	 {
	 	 	 	int t=check(x,y,j);
	 	 	 	if(t>maxn) {maxn=t,num=g[j][y]; continue; }
	 	 	 	if(t==maxn) {num+=g[j][y]; continue; }
			}
		    if(opt) printf("%d %d\n",maxn,num);
			 else printf("%d\n",maxn);		  
		}
	    for(j=0;j<=(1<<8)-1;++j)
	     {
	     	int t=slove(y,j);
	     	if(t==f[x][j]) {g[x][j]++; continue;}
	     	if(t>f[x][j]) {f[x][j]=t,g[x][j]=1; continue;}
		 }
	 }
	return 0;
}


posted @ 2016-08-19 16:34  lris0-0  阅读(113)  评论(0编辑  收藏  举报
过去的终会化为美满的财富~o( =∩ω∩= )m