动态规划

打气球的最大分数

http://www.nowcoder.com/questionTerminal/35119064d0224c35ab1ab612bffee8df

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

//递归
//int Func(vector<int>& arr, int L, int R) {
//    //此时只有一个气球,直接打爆
//    if (L == R) {
//        return arr[L - 1] * arr[L] * arr[R + 1];
//    }
//    //如过arr[L]或者arr[R] 是最后打爆的
//    int Max = max(arr[L - 1] * arr[L] * arr[R + 1] + Func(arr, L + 1, R),
//        arr[L - 1] * arr[R] * arr[R + 1] + Func(arr, L, R - 1));
//    //尝试每一中间位置最后被打爆
//    for (int i = L + 1; i < R; ++i) {
//        Max = max(Max, arr[L - 1] * arr[i] * arr[R + 1] + Func(arr, L, i - 1) +
//            Func(arr, i + 1, R));
//    }
//    return Max;
//}

int main() {

    int n;
    while (cin >> n) {
        vector<int> arr(n);
        for (int i = 0; i < n; ++i) {
            cin >> arr[i];
        }
        vector<int> v(n + 2);
        v[0] = 1;
        v[n + 1] = 1;
        for (int i = 0; i < n; ++i) {
            v[i + 1] = arr[i];
        }
        //动态规划
        //根据递归的终止条件确定初始值
        vector<vector<int>> dp(n + 2,vector<int>(n + 2));
        for (int i = 1; i <= n; ++i) {
            dp[i][i] = v[i - 1] * v[i] * v[i + 1];
        }
        //根据递归式可以看出,当前的dp值只与左边和下边有关,所以自底向上更新
        for (int L = n; L >= 1; --L) {
            for (int R = L + 1; R <= n; ++R) {

                //最后打爆v[L]的分数
                int final_L = v[L - 1] * v[L] * v[R + 1] + dp[L + 1][R];
                //最后打爆v[R]的分数
                int final_R = v[L - 1] * v[R] * v[R + 1] + dp[L][R - 1];
                dp[L][R] = max(final_L,final_R);
                //尝试最后打中间
                for (int k = L + 1; k < R; ++k) {
                    dp[L][R] = max(dp[L][R],v[L - 1] * v[k] * v[R + 1] + dp[L][k - 1] + dp[k + 1][R]);
                }
            }
        }
        cout << dp[1][n] << endl;
    }
    return 0;
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务