有 n 个学生站成一排,每个学生有一个能力值,牛牛想从这 n 个学生中按照顺序选取 k 名学生,要求相邻两个学生的位置编号的差不超过 d,使得这 k 个学生的能力值的乘积最大,你能返回最大的乘积吗?
输入描述:
每个输入包含 1 个测试用例。每个测试数据的第一行包含一个整数 n (1 <= n <= 50),表示学生的个数,接下来的一行,包含 n 个整数,按顺序表示每个学生的能力值 ai(-50 <= ai <= 50)。接下来的一行包含两个整数,k 和 d (1 <= k <= 10, 1 <= d <= 50)。
输出描述:
输出一行表示最大的乘积。
示例1
输入
3
7 4 7
2 50
输出
49
dp[i][j]:当选择的第j(从0开始计数)个人的idx是i时,最大的乘积
0 <= i < n
0 <= j < k
#include <climits>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
size_t n;
cin >> n;
vector<long long> students(n, 0);
for (size_t i=0; i<n; ++i) {
int power;
cin >> power;
students[i] = power;
}
int k, d;
cin >> k >> d;
vector<vector<long long>> dp_max(n, vector<long long>(k, 0));
vector<vector<long long>> dp_min(n, vector<long long>(k, 0));
long long max_power = INT8_MIN;
for (size_t row=0; row<n; ++row) {
max_power = max(max_power, students[row]);
dp_max[row][0] = students[row];// base case: 选择的第0个人的idx就是row时,乘积即s[row]
dp_min[row][0] = students[row];
}
// 遍历方向从k遍历
for (int col=1; col<k; ++col) {
for (int row=col; row<n; ++row) {
for (int idx=row-1; row-idx<=d && idx>=0; --idx) {
dp_max[row][col] = max(dp_max[row][col],
max(dp_max[idx][col-1] * students[row], dp_min[idx][col-1]*students[row]));
dp_min[row][col] = min(dp_min[row][col],
min(dp_min[idx][col-1] * students[row], dp_max[idx][col-1]*students[row]));
}
max_power = max(max_power, dp_max[row][col]);
}
}
cout << max_power <<endl;
return 0;
}
unzipstring
// 速记内容还原:
// 有一种速记方式,针对重复内容有一套独特的缩写规则:
// 重复的部分会被以 “(重复内容)<重复次数>” 形式记录,并且可能存在嵌套缩写关系。不重复的部分按照原样记录。
// 现给一个符合此速记方式的字符串 records,请以字符串形式返回复原后的内容。
// 注: records 仅由小写字母、数字及<, >, (, )组成。
// 输入:records = “abc(d)<2>e”
// 输出:“abcdde”
// 解释:字符串中出现 “(d)<2>”,表示 “d” 重复出现 2 次,因此返回复原后的内容 “abcdde”。
// 输入:records = “a(b©<3>d)<2>e”
// 输出:“abcccdbcccde”
// 解释:字符串中出现 “a(b©<3>d)<2>”,其中 “©<3>” 表示 “c” 出现 3 次,复原为 “ccc”;“(bcccd)<2>” 表示 “bcccd” 重复出现 2 次,复原为 “bcccdbcccd”。最终返回复原后内容 “abcccdbcccde”
// string UnzipString(string records) {
// }
#include <bits/stdc++.h>
#include <ostream>
using namespace std;
class S
{
public:
string func(string s)
{
int len = s.size();
stack<char> stk;
int repeated = 0;
string repeated_s = "";
string ret = "";
int has_k = 0;
for (int i=0; i<len; i++)
{
auto c = s[i];
if (c == '('){
repeated_s = func(s.substr(i+1));
int cnt = 1;
for (int j=i+1; j<len; j++)
{
if (s[j] == ')')
cnt--;
if (s[j] == '(')
cnt++;
if (cnt == 0){
i = j;
break;
}
}
}
else if (c == ')'){
return ret;
}
else if (c == '<'){
if (s[i+2] == '>'){
repeated = s[i+1]-'0';
i+=2;
} else{
repeated = 10;
i+=3;
}
for (int i =0; i<repeated; i++){
ret += repeated_s;
}
}else {
ret += s[i];
}
}
return ret;
}
};
int main()
{
S s;
auto tmp = s.func("a(b(c)<3>d)<2>e");
printf("tmp: %s\n", tmp.c_str());
}
// abc(d)<2>e ->abcdde
// a(b(c)<3>d)<2>e -> abcccdbcccde