E - Array Shrinking区间dp||dp

题:https://codeforces.com/contest/1312/problem/E

题意:对于一个序列可以选相邻俩个数进行合并成其数+1,问合成后的最小序列长度是多少

分析1:设f[][]表示区间[i,j]区间向前合成的最小长度,简单的模拟一下即可求出,最后dp往后考虑合并

#include<bits/stdc++.h>
using namespace std;
const int M=1e3+3;
int sta[M],f[M][M],a[M],ans[M];
int main(){
    int n;
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=1;i<=n;i++){
        int top=0;
        for(int j=i;j<=n;j++){
            int x=a[j];
            while(top&&sta[top]==x)
                top--,x++;
            sta[++top]=x;
            f[i][j]=top;
        }
    }
    memset(ans,0x3f,sizeof(ans));
    ans[0]=0;
    for(int i=1;i<=n;i++)
        for(int j=0;j<i;j++)
            ans[i]=min(ans[i],ans[j]+f[j+1][i]);
    cout<<ans[n]<<endl;
    return 0;
}
View Code

分析2:dp区间长度

#include<bits/stdc++.h>
using namespace std;
const int M=1e3+3;
int sta[M],f[M][M],a[M],ans[M];
int main(){
    int n;
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=1;i<=n;i++){
        int top=0;
        for(int j=i;j<=n;j++){
            int x=a[j];
            while(top&&sta[top]==x)
                top--,x++;
            sta[++top]=x;
            f[i][j]=top;
        }
    }
    memset(ans,0x3f,sizeof(ans));
    ans[0]=0;
    for(int i=1;i<=n;i++)
        for(int j=0;j<i;j++)
            ans[i]=min(ans[i],ans[j]+f[j+1][i]);
    cout<<ans[n]<<endl;
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/starve/p/12458439.html