UVA 10559 Blocks

本文讨论了如何使用动态规划解决方块消除游戏问题,通过递归和备忘录技术实现最优解,每步操作都涉及颜色相同的方块进行消除,并计算得分。文章详细解释了解题思路和算法实现,提供了具体的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:方块消除游戏,给你一个n个方块的序列,相同颜色的一段可以同时消掉,得分为 len^2,问你得分最高时多少?

思路:借用POJ discuss 里的一句话来说,这道题真是优质DP啊。。。  具体解题思路可以看黑书,也可以看这里:http://wenku.baidu.com/view/83d0a76925c52cc58bd6bea8.html,说的很不错。我只是简单的填个坑:设 d[ i ][ j ][ k ] 表示 区域 i 到 区域 j ,区域 j 与后面的 k 个方块相连消掉的最大值,其中 i ~j - 1 只能与自己 i ~ j 中的区域相连。d[ i ][ j ][ k ] = max(d[ i ][ j - 1][ 0 ] + (k+len[ j ])^2, d[ i ][ p ][ k + len[ j ] ] + d[p + 1][ j ][ 0 ] ),其中 col[ p ] == col[ j ] 。

这种题目真心感觉自己想不出来,用一维来表示未来,而且题目虽然A了,但是感觉还是不是很理解,在做几道,回过头来看吧。。。 = =

代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int MAXN = 222;

int d[MAXN][MAXN][MAXN];

int col[MAXN],num[MAXN];

int dfs(int i,int j,int k)
{
    if(i > j) return 0;
    if(d[i][j][k] != -1) return d[i][j][k];
    d[i][j][k] = dfs(i,j-1,0) + (k + num[j])*(k + num[j]);
    for(int pos = j-1;pos >= i; pos --)
    {
        if(col[pos] == col[j])
            d[i][j][k] = max(d[i][j][k],dfs(i,pos,k + num[j]) + dfs(pos + 1,j-1,0));
    }
    return d[i][j][k];
}

int main()
{
    int _;
    scanf("%d",&_);
    for(int cas = 1;cas <= _ ;cas ++)
    {
        int n;
        scanf("%d",&n);
        int tot = 0;
        memset(d,-1,sizeof(d));
        for(int i = 1;i<=n;i++)
        {
            int a;
            scanf("%d",&a);
            if(tot == 0 || a != col[tot])
            {
                d[tot][tot][0] = num[tot]*num[tot];
                tot++;
                col[tot] = a;
                num[tot] = 1;
            }
            else
            {
                num[tot]++;
            }
        }
        //for(int i = 1;i<=tot;i++)
            //printf("col[i] = %d,num[i] = %d\n",col[i],num[i]);
        printf("Case %d: %d\n",cas,dfs(1,tot,0));
    }
    return 0;
}

/*

5
1 1 3 1 1

*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值