这题还是很考验思维的,dp倒是很容易

如果采用状压把所有二进制位考虑进来倒是能搞

但是这数最大50位,GG~

然 后 我 就 在 想 可 不 可 以 从 高 位 一 位 一 位 来 贪 心 然后我就在想可不可以从高位一位一位来贪心

验 证 某 一 位 能 否 达 到 是 很 简 单 的 验证某一位能否达到是很简单的

关 键 是 判 断 高 位 可 行 后 , 如 何 判 断 低 位 在 满 足 高 位 的 情 况 下 可 行 关键是判断高位可行后,如何判断低位在满足高位的情况下可行 ,

这个后效性把我难死了

但 是 啊 ! ! 与 操 作 是 具 有 可 叠 加 的 性 质 的 但是啊!!与操作是具有可叠加的性质的 !!

比 如 这 次 判 断 了 高 位 x 二 进 制 可 行 比如这次判断了高位x二进制可行 x

现 在 要 判 断 x − 1 位 二 进 制 在 满 足 x 位 二 进 制 可 行 的 情 况 下 是 否 可 行 现在要判断x-1位二进制在满足x位二进制可行的情况下是否可行 x1x

很 简 单 , 那 这 次 d p 去 判 断 每 组 有 ( 1 < < x ) + ( 1 < < ( x − 1 ) ) 很简单,那这次dp去判断每组有(1<<x)+(1<<(x-1)) ,dp(1<<x)+(1<<(x1))

如 果 成 功 , 答 案 加 上 ( 1 < < ( x − 1 ) ) 如果成功,答案加上(1<<(x-1) ) ,(1<<(x1))

然 后 下 次 判 断 在 这 个 基 础 上 继 续 与 叠 加 判 断 然后下次判断在这个基础上继续与叠加判断

至于DP判断,很多人用区间DP

其实线性dp完全更好理解吧的,不知道他们怎么想的,复杂度也不会差

#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,k,a[52],ans,dp[52][52],pre[52];
bool isok( int x )//判断第x位 
{
	memset(dp,0,sizeof(dp));
	dp[0][0]=1;
	for(int i=1;i<=n;i++)//枚举物品 
	for(int j=1;j<=min(i,k);j++)//枚举组
	{
		for(int q=0;q<i;q++)//从前面的物品转移而来
		{
			if( (x&(pre[i]-pre[q]) )!=x )	continue;	
			dp[i][j]|=dp[q][j-1];
		} 
	}
	if( dp[n][k] )	return true;
	return false; 
}
signed main()
{
	cin >> n >> k;
	for(int i=1;i<=n;i++)	cin >> a[i],pre[i]=pre[i-1]+a[i];
	for(int i=60;i>=0;i--)
	{
		int temp=( (int)1<<i );
		if( isok( ans|temp ) )
			ans|=temp;
	}
	cout << ans;
}