题解 | #合唱队#

合唱队

http://www.nowcoder.com/practice/6d9d69e3898f45169a441632b325c7b4

计算最少出列多少位同学,使得剩下的同学排成合唱队形
说明:
N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足存在i(1<=i<=K)使得T1<T2<......<Ti-1<ti>Ti+1>......>TK。
你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。
思路:动态规划
(1):找[0, j]长度的数组中最长递增子序列(动态规划实现)
1.dp[i]:表示[0, i]内最长递增子序列长度
2.动态方程:如果nums[i] > nums[i-1],则dp[i] = max(dp[i], dp[i - 1] + 1)
3.初始化条件
dp[i] = 1
4.遍历顺序
从左往右</ti>

vector<int> increasingSequence(const vector<int>& nums){
    vector<int> dp(nums.size(), 1);
    for(int i = 1; i < dp.size(); ++i){
        for(int j = 0; j < i; ++j){
            if(nums[i] > nums[j])
                dp[i] = max(dp[i], dp[j] + 1);
        }
    }
    return dp;
}

(2):找[j, nums.size() - 1]长度的数组中最长递减子序列(动态规划实现)
1.dp[i]:表示[i, nums.size() - 1]内最长递减子序列长度
2.动态方程:如果nums[i] > nums[i+1],则dp[i] = max(dp[i], dp[i + 1] + 1)
3.初始化条件
dp[i] = 1
4.遍历顺序
从右往左

vector<int> decreasingSequence(const vector<int>& nums){
    vector<int> dp(nums.size(), 1);
    int n = nums.size();
    for(int i = n - 2; i >= 0; --i){
        for(int j = n - 1; j > i; --j){
            if(nums[i] > nums[j])
                dp[i] = max(dp[i], dp[j] + 1);
        }
    }
    return dp;
}

最终实现代码

#include<iostream>
#include<vector>
using namespace std;
vector<int> increasingSequence(const vector<int>& nums);
vector<int> decreasingSequence(const vector<int>& nums);
int main(){
    int n;
    while(cin >> n){
        vector<int> high;
        int h;
        for(int i = 0; i < n; ++i){
            cin >> h;
            high.push_back(h);
        }
        vector<int> v1 = increasingSequence(high);
        vector<int> v2 = decreasingSequence(high);
        int maxLen = v1[0] + v2[0] - 1;
        for(int i = 1; i < v1.size(); ++i){
            if(v1[i] + v2[i] - 1 > maxLen)
                maxLen = v1[i] + v2[i] - 1;
        }
        cout << high.size() - maxLen << endl;
    }
    return 0;
}

vector<int> increasingSequence(const vector<int>& nums){
    vector<int> dp(nums.size(), 1);
    for(int i = 1; i < dp.size(); ++i){
        for(int j = 0; j < i; ++j){
            if(nums[i] > nums[j])
                dp[i] = max(dp[i], dp[j] + 1);
        }
    }
    return dp;
}

vector<int> decreasingSequence(const vector<int>& nums){
    vector<int> dp(nums.size(), 1);
    int n = nums.size();
    for(int i = n - 2; i >= 0; --i){
        for(int j = n - 1; j > i; --j){
            if(nums[i] > nums[j])
                dp[i] = max(dp[i], dp[j] + 1);
        }
    }
    return dp;
}
全部评论

相关推荐

点赞 评论 收藏
分享
在秋招的香菇很中二:把实践经历、校园经历删了,把课设包装成项目经历写上去。
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务