Array Shrinking(CodeForces - 1312E )

题目链接
题意:给你一组数,如果前一个数等于后一个数,这两个数就可以合成一个新数,并且新数的值为原数加1,问得到数组的最小长度

区间dp题,难度在于连续多个相同的数任意两两合并怎么区别表示。

#include <iostream>
#include <cstring>
using namespace std;
#define mann 0x3f3f3f3f
long long int n,t,k,x,m,i,j;
long long int mod=998244353;
long long int a[1005][1005],d[1005][1005];
using namespace std;
string s;

int main()
{
     
    cin>>n;
    for(i=1; i<=n; i++)
    {
     
        cin>>a[i][i];//为了区分连续的多个相同的数(如:333)之间任意的两两和成情况,二维数组第一个表示初位置,第二个表示末位置。
    }
    for(i=1; i<=n; i++)
    {
     
        for(j=1; j<=n; j++)
            d[i][j]=j-i+1;//记录区间长度
    }
    for(int len=2; len<=n; len++)
    {
     
        for(int i=1,j=len+i-1; j<=n; j++,i++)
        {
     
            for(int k=i; k<j; k++)
            {
     
                if(d[i][k]==1&&d[k+1][j]==1&&a[i][k]==a[k+1][j])//判断是否是相邻的两个数,两个数是否相等
                {
     
                    d[i][j]=1;//i,j两个数合并成了一个
                    a[i][j]=a[i][k]+1;//原位置i,j两个数合并后的新值
                }
                d[i][j]=min(d[i][j],d[i][k]+d[k+1][j]);//更新长度,如果有合并情况就取小的
            }
        }
    }
    cout<<d[1][n]<<endl;
    return 0;
}

你可能感兴趣的:(笔记)