✏️ 纠错
第 134 题 / 共 155 题
题目描述
班主任计划将班级里的 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≤104。
你真棒!
📝 题目解析
【题目大意】将n名学生进行分组,要求每位学生都必须被分配到某个小组中,规定一个由k人组成的小组其积极度为ak,需计算出积极度总和的最大值。
【考纲知识点】动态规划知识
【解题思路】在本题中,参数n兼具两个含义,既表示物品的数量,又代表背包的容量。第k个物品的体积为k,价值为ak。由于每种物品可被选用的次数不受限制,能够被使用无数次,因此该问题属于完全背包问题。 本题的要点是熟悉完全背包类型的动态规划求解。
参考程序
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1005;
int n;
int a[N], f[N];
int main() {
int ans = 0;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
for (int j = i; j <= n; j++)
f[j] = max(f[j], f[j - i] + a[i]);
}
for (int i = 1; i <= n; i++)
ans = max(ans, f[n]);
printf("%d\n", ans);
return 0;
}