1275.B 动态规划

题目

由于wangjp小学生数学题都不会做,给大家在考场上带来了很大的麻烦,他决心好好学习数学
本次他挑选了位运算专题进行研究 他发明了一种叫做“wangjp运算”的运算符:a$b =( (a&b) + (a|b) )>>1他为了练习,写了n个数在黑板上(记为a[i]) 并对任意相邻两个数进行“wangjp运算”,把两数擦去,把结果留下 这样操作n-1次之后就只剩了1个数,
这个数可能是什么?
将答案从小到大顺序输出
30% n<=10 0<=a[i]<=7 70% n<=150 0<=a[i]<=3 100% n<=150 0<=a[i]<=7

题解

暴力或观察数据可得部分分

正解动规
设f[i][j][0~ 7]表示区间[i,j]可不可以达成数0~7
易得转移方程
为了省时间,运算过程用位运算且用bool型存动规判定数组。观察数据可发现实际上a$b =( (a&b) + (a|b) )>>1就是(a+b)/2

代码

#include <cstdio>
#include <iostream>

using namespace std;

int n,b,c,d,m;
int a[200];
bool f[200][200][10];

int main(){
	scanf("%d",&n);
	for (int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		if (a[i]>1) b=1;
		if (a[i]>m) m=a[i];
		if (a[i]!=3) d=1;
		if (a[i]==0) c=1;
		f[i][i][a[i]]=1;
	}	
	if (!b&&c) {printf("0");return 0;}
	if (!d) {printf("3");return 0;}
	for (int e=2;e<=n;e++)
		for (int i=1;i+e-1<=n;i++){
			int l=i,r=i+e-1;
			for (int k=0;k<=m;k++)
			for (int t=0;t<=m;t++)
				for (int j=l;j<r;j++)
					f[l][r][(k+t)>>1]|=f[l][j][k]&f[j+1][r][t];
		}
	int c;
	for (c=0;c<=m;c++)
		if (f[1][n][c]) printf("%d ",c);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值