zoukankan      html  css  js  c++  java
  • Blocks POJ

    题意:有一排box,各有不同的颜色。你可以通过点击某个box使得与其相邻的同色box全部消掉,然后你可以得到的分数为消去长度的平方,问怎样得到最高分?

    题解:考虑用一维dp,/*dp[i]为1~i个block(我们称颜色相同的一段box为一个block)所能得到的最大得分*/发现无法递推。

       考虑用二维dp,dp[i][j]为从block i 到 block j 的最大得分

          考虑最右端的j1.直接消除j

                2。它和左边的某个block合并:dp[i][k-1]+dp[k+1][j-1]+(len[k]+len[j])^2

       发现无法计算,因为合并一块以后还能继续合并,可能得到更优解。

       所以用三维dp dp[i][j][extra_len] 代表从block i 到block j ,且将j右边长为extra_len的box与 bolck j 合并时(也就是说其颜色与j相同)能取得的最大值。

    代码:

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    const int maxn = 200;
    struct block {
        int color;
        int len;
    }segment[maxn];
    int score[maxn][maxn][maxn];
    int click_box(int start, int end, int extra_len) {
        int i, res, temp;
        int &now = score[start][end][extra_len];
        if (now> 0)return now;//记忆递归
        res = segment[end].len + extra_len;
        res *= res;
        if (start == end) { return now = res;}//递归边界
        res += click_box(start, end - 1, 0);//直接消掉extra_len+end
        for (i = end - 1; i >= start; i--) {
            if (segment[i].color != segment[end].color)continue;
            temp = click_box(start, i, segment[end].len + extra_len)+click_box(i+1,end-1,0);//找到前面某个i 一起消掉
            if (temp <= res)continue;
            res = temp;
        }
        now = res;
        return now;
    }
    int main() {
        int t, n, i, j, end, color;
        cin >> t;
        for (int i = 1; i <= t; i++) {
            cin >> n; end = 0;
            cin >> segment[end].color;
            segment[end].len = 1;
            for (j = 1; j < n; j++) {
                cin >> color;
                if (color == segment[end].color)segment[end].len++;
                else end++, segment[end].color = color, segment[end].len = 1;
            }
            memset(score, 0, sizeof(score));
            cout << "Case " << i << ": " << click_box(0, end, 0) << endl;
        }
        system("pause");
        //return 0;
    }
    成功的路并不拥挤,因为大部分人都在颓(笑)
  • 相关阅读:
    Python基础之初始编码
    Excel图表编辑---表格移动,样式修改
    Python基础之Python的变量、常量
    刷题62. Unique Paths
    刷题56. Merge Intervals
    刷题55. Jump Game
    刷题53. Maximum Subarray
    刷题49. Group Anagrams
    刷题48. Rotate Image
    刷题46. Permutations
  • 原文地址:https://www.cnblogs.com/SuuT/p/8795783.html
Copyright © 2011-2022 走看看