1 条题解

  • 0
    @ 2025-4-17 16:23:38

    大概意思是说,有这样一个游戏,就是,第一个图那样,好多盒子,然后,打其中一个盒子,那些和这个盒子同个颜色并且相邻的盒子都和这个盒子一起消失,并且得到 消失的盒子的个数的平方 分。。问,如何才能得到最多分(类似与祖玛游戏)

    这道题是这样做的:刚开始的时候,将输入的盒子按照颜色相同的盒子放为一类,类里面有这个类的颜色和这个类有多少个盒子。。比如第一附图,那么block[0].color=1,block[0].len=1;block[1].color=2,block[1].len=4;block[2].color=3,block[2].len=3;block[3].color=1,block[3].len=1。 然后,对于dp(l, r, len)的意思是,在条件 “区间[l, r]里并且后面有连续len个盒子和在r位置的盒子同颜色的盒子” 下,得到最高的分数是多少。注意,这里的条件是说,r后面有连续len个盒子和它同颜色,因为,在中间的不同颜色的盒子已经被消去了。 那么,对于dp(l,r,len)就有下面两个方法可以得到结果,也就是要取这两个方法的最大值。 dp(l,r,len) = max( dp(l, r-1, 0)+(ex_len+n_v[r].len)(ex_len+n_v[r].len), dp(l, k, ex_len+n_v[r].len)+dp(k+1, r-1, 0)) dp(l, r-1, 0)+(ex_len+n_v[r].len)(ex_len+n_v[r].len) 是说,直接把r和r后面的ex_len个盒子都消去,得到的分数。 dp(l, k, ex_len+n_v[r].len)+dp(k+1, r-1, 0) 是说,找到中间一个k个块,它和r的颜色是相同的,那么,就把k个块和r和ex_len一起消去,就是dp(l, k, ex_len+n_v[r].len),加上把k和r中间的那部分消去的分数,就是dp(k+1, r-1, 0),这里对于每个情况,又会有两个递归,就可以向前遍历所有可能情况了。

    #include <iostream>
    #include <vector>
    #include <cstring>
    using namespace std;
    struct block{
        int color;  //这个块的颜色
        int len;  //这个块的大小
        block(int _color, int _len):color(_color), len(_len){};
    };
    vector<block> n_v;
    int info[200][200][200];
    int dp(int l, int r, int ex_len){
        if(info[l][r][ex_len]>0) return info[l][r][ex_len];
        if(l==r) return (n_v[l].len+ex_len)*(n_v[l].len+ex_len);
        int temp = dp(l, r-1, 0)+(ex_len+n_v[r].len)*(ex_len+n_v[r].len);
        for (int k = r-1; k >= l ; k--) {
            if(n_v[k].color == n_v[r].color){
                //找到一个合适的了
                temp = max(temp, dp(l, k, ex_len+n_v[r].len)+dp(k+1, r-1, 0));
            }
        }
        info[l][r][ex_len] = temp;
        return temp;
    }
    int main()
    {
        int t, c=1;
        cin>>t;    //多少个测试用例
        while(t--){
            memset(info, 0, sizeof(info));
            n_v.clear();
            int n;     //多少个盒子
            cin>>n;
            int num;
            cin>>num;
            n_v.push_back(block(num, 1));
            for (int i = 1; i < n; ++i) {
                cin>>num;
                if(num==(n_v.end()-1)->color){
                    //和上一个颜色块的颜色一样,放到同一个结构体里面
                    (n_v.end()-1)->len++;
                }
                else{
                    //颜色不同,新加一个结构体元素
                    n_v.push_back(block(num, 1));
                }
            }
            cout<<"Case "<<c++<<": "<<dp(0, n_v.size()-1, 0)<<endl;
        }
        return 0;
    }
    • 1

    信息

    ID
    391
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者