poj 1390 DP

dp[prenum][pos1][pos2] 表示当之前的个数为prenum时pos1到pos2的最大值

一开始做的时候我增加了一个之前的值是什么颜色的状态,直接内存不够用啊了,最后发现其实在从第一个处理的时候,要么直接消除,要么和之后颜色一样的一起消除,所以可以把颜色这个维度去掉

然后状态转移就是  之前的prnum和pos1个要么直接消除,要么和之后相同的一起消除

AC代码如下:

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

struct Node{
    int id;
    int num;
};

int N;
int dp[210][210][210];
Node node[210];
int tot;

int DFS( int prenum, int pos1, int pos2 ){
    if( pos1 > pos2 ){
        return 0;
    }
    if( dp[prenum][pos1][pos2] != -1 ){
        return dp[prenum][pos1][pos2];
    }
    int ans = 0;
    int temp = prenum + node[pos1].num;
    ans = max( ans, temp * temp + DFS( 0, pos1 + 1, pos2 ) );
    for( int i = pos1 + 1; i <= pos2; i++ ){
        if( node[i].id == node[pos1].id ){
            ans = max( ans, DFS( 0, pos1 + 1, i - 1 ) + DFS( temp, i, pos2 ) );
        }
    }
    return dp[prenum][pos1][pos2] = ans;
}

int main(){
    int T, Case = 1;

    cin >> T;
    while( T-- ){
        cin >> N;
        tot = 0;
        cin >> node[++tot].id;
        node[tot].num = 1;
        for( int i = 1; i < N; i++ ){
            int temp;
            cin >> temp;
            if( temp == node[tot].id ){
                node[tot].num++;
            }else{
                tot++;
                node[tot].id = temp;
                node[tot].num = 1;
            }
        }

        memset( dp, -1, sizeof( dp ) );
        printf( "Case %d: %d\n", Case++, DFS( 0, 1, tot ) );
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值