CF607B Zuma(区间dp)

CF607B Zuma

题目描述

\(\texttt{Genos}\) 最近在他的手机上下载了祖玛游戏。在祖玛游戏里,存在 \(n\) 个一行的宝石,第 \(i\) 个宝石的颜色是 \(C_i\)。这个游戏的目标是尽快的消灭一行中所有的宝石。

在一秒钟,\(\texttt{Genos}\) 能很快的挑选出这些有颜色的宝石中的一个回文的、连续的子串,并将这个子串移除。每当一个子串被删除后,剩余的宝石将连接在一起,形成一个新的行列。

你的任务是:求出把整个宝石串都移除的最短时间。

输入格式

第一行包含一个整数 \(n(1 \le n \le 500)\),表示宝石串的长度。第二行包含 \(n\) 个被空格分开的整数,第 \(i(1 \le i \le n)\) 个表示这行中第 \(i\) 个珠子的颜色。

输出格式

输出一个整数,把这行珠子移除的最短时间。

输入输出样例 #1

输入 #1

3
1 2 1

输出 #1

1

输入输出样例 #2

输入 #2

3
1 2 3

输出 #2

3

输入输出样例 #3

输入 #3

7
1 4 4 2 3 2 1

输出 #3

2

说明/提示

在第一个例子中,\(\texttt{Genos}\) 可以在一秒钟就把这行珠子全部移走。在第二个例子中,\(\texttt{Genos}\) 一次只能移走一个珠子,所以移走三个珠子花费他三秒。在第三个例子中,为了达到 \(2\) 秒的最快时间,先移除回文串 \(\texttt{4 4}\),再移除回文串 \(\texttt{1 2 3 2 1}\)

感谢 @Administrator2004 提供的翻译

#include<iostream>
#include<cstring>
using namespace std;
const int N=500+5;
int f[N][N];
int a[N];
int main(){
    int n;
    cin>>n;
    memset(f,0x3f,sizeof(f));
    for(int i=1;i<=n;i++){
        cin>>a[i];
        f[i][i]=1;
        f[i][i-1]=1;// 这里通过把长度为0的字符串都赋值为1来应对长度为2的会问串的情况
    }
    for(int len=2;len<=n;len++){
        for(int l=1;l+len-1<=n;l++){
            int r=len+l-1;
            if(a[l]==a[r])f[l][r]=min(f[l+1][r-1],f[l][r]);
            for(int k=l;k<r;k++)f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]);//首尾消除不一定比中间两个区间合并小

        }
    }
    cout<<f[1][n];
    return 0;
}
posted @ 2025-02-25 20:03  郭轩均  阅读(37)  评论(0)    收藏  举报