洛谷题解:P16304 [蓝桥杯 2026 省 Java C 组] 抽奖活动

题意

给出 n n n 数,可以执行 k k k 次操作,每次从剩余的球里选一个,保证左边的数的数量是右边的倍数,求最大拿到的数的和。

思路

由于 n n n 很小,可以考虑压装。 d p x dp_x dpx 表示当前选择情况为 x x x 的最大权值。其中, x x x 的二进制位表示它对应的数是否被选择。

复杂度 O ( n 2 n ) \mathcal{O}(n2^n) O(n2n)。

代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n,k,a[21],dp[2000000],mx;
int main(){
	//读入
	cin>>n>>k,memset(dp,-1,sizeof dp),dp[0]=0;
	for(int i=1;i<=n;i++) cin>>a[i];
	//枚举x
	for(int x=0;x<=(1<<n)-1;mx=max(mx,dp[x]),x++)
		if(int co=__builtin_popcount(x);dp[x]!=-1&&co<k){
			//判断是否能继续扩展
			for(int i=1,l=0,r;i<=n;i++)//扩展
				if(!(x&(1<<(i-1)))){//这个数没有被选上
					r=n-co-l-1;//计算右边的数的个数
					//满足要求就更新最大值
					if(r&&!(l%r)) dp[x|(1<<(i-1))]=max(dp[x|(1<<(i-1))],dp[x]+a[i]);
					l++;//左边的数字增加
				}
		}
	cout<<mx;//输出最大值
	return 0;
}

原文链接

相关推荐
凡人叶枫2 分钟前
Effective C++ 条款40:明智而审慎地使用多重继承
java·数据库·c++·嵌入式开发·effective c++
放弃 治疗5 分钟前
宝塔面板安装 JDK 完整教程|Java 环境配置详解
java·开发语言
仍然.7 分钟前
算法题目---BFS解决最短路问题
算法·宽度优先
ShineWinsu8 分钟前
对于Linux:线程局部存储(TLS)和线程封装的解析
linux·c++·面试·线程·tls·线程封装·线程局部存储
工头阿乐8 分钟前
使用Conan构建现代C++项目:完整指南
开发语言·c++
渡众机器人8 分钟前
第八届全球校园人工智能算法精英大赛-算法应用赛-空地协同侦排挑战赛规则
人工智能·算法
至此流年莫相忘17 分钟前
Spring 依赖注入三剑客:@Autowired、@Resource 与 @RequiredArgsConstructor 深度对比与实战指南
java·数据库·spring
wayz1120 分钟前
Overlap:HWMA(Holt-Winter移动平均线)技术指标详解
算法·金融·数据分析·量化交易·特征工程
零陵上将军_xdr29 分钟前
为什么DCL单例要加volatile?——CPU乱序执行与内存屏障
java·linux
Shadow(⊙o⊙)37 分钟前
专题四:前缀和
数据结构·算法