合唱团/unzipstring-笔试题

合唱团

有 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 
#include 
#include 
#include 

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 
#include 
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

你可能感兴趣的:(Leetcode算法,leetcode)