题目描述
小明在工作之余喜欢在电子书城阅读不同的书籍并且获得最大的满足感,因此根据书城针对每本书籍的评分收集了 n 个书籍的打分清单 books,例如第一本书的打分 books[0]=5 代表该书的满意程度为 5,第二本书 books[1]=-2 代表该书的满意程度为 -2。
阅读每本书花费的都是 1 单位时间,time 定义为阅读本书及之前所有书的时间之和。因此第一本阅读的书籍 time[0]=1,第二本阅读的书籍 time[1]=2,第三本阅读的书籍 time[2]=3 并依此类推。
每本书籍的【快乐时间】系数为阅读该书籍和之前每本书籍所花费的时间乘以对这本书籍的满意程度,即 time[i] * books[i],其中 i 从 0 开始。
小明想了解自己如何安排阅读计划才能获得最大的快乐时间,请帮忙计算一下阅读给定书籍【快乐时间】总和最大的值是多少,可以按照任意顺序调整阅读书籍顺序(即每本书对应的 time[i] 是可以对调的),也可以放弃阅读某些书籍。
输入描述
- 输入为字符串,字符串内容为代表每本书籍的喜爱指数,例如 books = [4,3,2],其中 1 ≤ n ≤ 500,满意程度 -1000 ≤ books[i] ≤ 1000。
输出描述
输出为数字,代表最大的快乐时间,例如 20,按照原来顺序相反的时间阅读书籍 (2 × 1 + 3 × 2 + 4 × 3 = 20),评分越高的书籍越后面阅读可以获得最大的快乐时间。
用例输入
4,3,2
20
说明:按照原来顺序相反的时间阅读书籍(2 * 1 + 3 * 2 + 4 * 3 = 20
),满意值越高的书籍越后面读可以获得最大的快乐值。
-1,-4,-5
0
说明:这些书籍满意值都很低,所以不阅读任何书籍可以获得最大的快乐值。
-1,-8,0,5,-9
14
说明:去掉第二个和最后一本书籍,最大的快乐时间系数和为(-1 * 1 + 0 * 2 + 5 * 3 = 14
)。
解题思路
- 输入处理:
- 使用字符串流将输入的满意值字符串分割为整数,并存储到一个向量中。
- 排序:
- 对所有书籍的满意值进行升序排序。排序后,满意值较低的书籍排在前面,满意值较高的书籍排在后面。
- 计算最大快乐值:
- 从排序后的满意值列表中,尝试从每本书开始读,并计算从该书开始读到最后一本书的总快乐值。
- 对于每本书,计算从该书开始读的快乐值总和:
- 第
i
本书的快乐值为(i + 1) * 满意值
,其中i
是从当前书开始的索引。
- 第
- 更新最大快乐值。
- 贪心选择:
- 通过遍历所有可能的起始书籍,找到最大快乐值。如果某本书的满意值为负,可能会导致总快乐值降低,因此可以选择跳过某些书。跳过的一定是满意值最低的。
代码
#include <iostream>
#include <vector>
#include <queue>
#include <sstream>
#include <string>
#include <stack>
#include <algorithm>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string input;
getline(cin, input);
vector<int> data;
std::istringstream iss(input);
string token;
while (getline(iss, token, ',')) {
data.push_back(stoi(token));
}
int size = data.size();
sort(data.begin(), data.end());
int res = 0;
for (int i = 0; i < size; i++) {
// 从第 i 本开始阅读后面的全部
int temp = 0;
for (int j = i; j < size; j++) {
temp += (j - i + 1) * data[j];
}
res = max(res, temp);
}
cout << res;
}