视频讲解:GESP202506 六级 学习小组-信息学奥赛GESP等级考试真题解析
一、原题
题目描述
班主任计划将班级里的 n 名同学划分为若干个学习小组,每名同学都需要分入某一个学习小组中。观察发现,如果一个学习小组中恰好包含 k 名同学,则该学习小组的讨论积极度为 ak。
给定讨论积极度 a1,a2,...,an,请你计算将这 n 名同学划分为学习小组的所有可能方案中,讨论积极度之和的最大值。
输入格式
第一行,一个正整数 n,表示班级人数。
第二行,n 个非负整数 a1,a2,...,an,表示不同人数学习小组的讨论积极度。
输出格式
输出共一行,一个整数,表示所有划分方案中,学习小组讨论积极度之和的最大值。
输入输出样例
输入 #1
4
1 5 6 3
输出 #1
10
输入 #2
8
0 2 5 6 4 3 3 4
输出 #2
12
说明/提示
对于 40% 的测试点,保证 1≤n≤10。
对于所有测试点,保证 1≤n≤1000,0≤ai≤10^4。
二、做题思路
1)填充数据

cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
//1)填充数据
//1.1)确定数量n
int n;cin>>n;
//1.2)每种人数的积极度
int a[1005]={};
for(int i=1;i<=n;i++) cin>>a[i];
return 0;
}
2)动态规划:计算当前人数的最优解

cpp
//1)填充数据
//....
//2.1)dp初始化
long long dp[1005]={};
//2.2)循环每种人数
for(int i=1;i<=n;i++){
//2.3)加入这种人数的最优解
for(int j=i;j<=n;j++){
//不拿:dp[j]
//拿:a[i]+dp[j-i]
dp[j]=max(dp[j],a[i]+dp[j-i]) ;
}
}
cout<<dp[n];
三、答案
cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
//1)填充数据
//1.1)确定数量n
int n;cin>>n;
//1.2)每种人数的积极度
int a[1005]={};
for(int i=1;i<=n;i++) cin>>a[i];
//2)动态规划:计算当前人数的最优解
//2.1)dp初始化
long long dp[1005]={};
//2.2)循环每种人数
for(int i=1;i<=n;i++){
//2.3)加入这种人数的最优解
for(int j=i;j<=n;j++){
//不拿:dp[j]
//拿:a[i]+dp[j-i]
dp[j]=max(dp[j],a[i]+dp[j-i]) ;
}
}
cout<<dp[n];
return 0;
}