zoukankan      html  css  js  c++  java
  • [Educational Codeforces Round 83 ] E. Array Shrinking

    [Educational Codeforces Round 83 ] E. Array Shrinking - (区间DP)

    E. Array Shrinking

    time limit per test

    2 seconds

    memory limit per test

    256 megabytes

    input

    standard input

    output

    standard output

    You are given an array a1,a2,…,ana1,a2,…,an. You can perform the following operation any number of times:

    • Choose a pair of two neighboring equal elements ai=ai+1ai=ai+1 (if there is at least one such pair).
    • Replace them by one element with value ai+1ai+1.

    After each such operation, the length of the array will decrease by one (and elements are renumerated accordingly). What is the minimum possible length of the array aa you can get?

    Input

    The first line contains the single integer nn (1≤n≤5001≤n≤500) — the initial length of the array aa.

    The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤10001≤ai≤1000) — the initial array aa.

    Output

    Print the only integer — the minimum possible length you can get after performing the operation described above any number of times.

    Examples

    input

    Copy

    5
    4 3 2 2 3
    

    output

    Copy

    2
    

    input

    Copy

    7
    3 3 4 4 4 3 3
    

    output

    Copy

    2
    

    input

    Copy

    3
    1 3 5
    

    output

    Copy

    3
    

    input

    Copy

    1
    1000
    

    output

    Copy

    1
    

    Note

    In the first test, this is one of the optimal sequences of operations: 44 33 22 22 33 →→ 44 33 33 33 →→ 44 44 33 →→ 55 33.

    In the second test, this is one of the optimal sequences of operations: 33 33 44 44 44 33 33 →→ 44 44 44 44 33 33 →→ 44 44 44 44 44 →→ 55 44 44 44 →→ 55 55 44 →→ 66 44.

    In the third and fourth tests, you can't perform the operation at all.

    题意:

    给定一个含有n个整数的数组,你可以将两个相邻且相等的数(X)合并成一个(X+1),其他的数位置和数值都不变,问当你在最优操作的情况下,最少能剩下多少个元素?

    思路:

    数据范围考虑用区间DP,

    定义状态:(dp[i][j])表示数组(a_i,a_{i+1},dots,a_{j}) 可以合并的最短长度。

    辅助数组:(b[i][j])表示数组(a_i,a_{i+1},dots,a_{j}) 可以合并的最短长度时的数值。

    转移:

    不合并时:

    枚举区间([i,j])中的k,(dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j]))

    合并元素时:

    (dp[i][k] = 1 , dp[k + 1][j] = 1 , b[i][k] = b[k + 1][j])(dp[i][j] = 1,b[i][j] = b[i][k] + 1)

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #include <sstream>
    #include <bitset>
    #define ALL(x) (x).begin(), (x).end()
    #define sz(a) int(a.size())
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
    #define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
    #define du2(a,b) scanf("%d %d",&(a),&(b))
    #define du1(a) scanf("%d",&(a));
    using namespace std;
    typedef long long ll;
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
    ll powmod(ll a, ll b, ll MOD) { if (a == 0ll) {return 0ll;} a %= MOD; ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
    ll poww(ll a, ll b) { if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a ;} a = a * a ; b >>= 1;} return ans;}
    void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    inline long long readll() {long long tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
    inline int readint() {int tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
    const int maxn = 510;
    const int inf = 0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    int n;
    int a[maxn];
    int b[maxn][maxn];
    int dp[maxn][maxn];
    int main()
    {
        //freopen("D:\code\text\input.txt","r",stdin);
        //freopen("D:\code\text\output.txt","w",stdout);
        n = readint();
        repd(i, 1, n)
        {
            a[i] = readint();
            b[i][i] = a[i];
        }
        repd(i, 1, n)
        {
            repd(j, i, n)
            {
                dp[i][j] = j - i + 1;
            }
        }
        repd(len, 2, n)
        {
            repd(i, 1, n - len + 1)
            {
                int j = i + len - 1;
                repd(k, i, i + len - 2)
                {
                    dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j]);
                    if (dp[i][k] == 1 && dp[k + 1][j] == 1 && (b[i][k] == b[k + 1][j]))
                    {
                        dp[i][j] = 1;
                        b[i][j] = b[i][k] + 1;
                    }
                }
            }
        }
        printf("%d
    ", dp[1][n] );
        return 0;
    }
    
    
    
    
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    c++继承中的内存布局
    函数调用的原理4点:函数产生名不同,压栈顺序不同,不应由客户清理,客户清理则可执行文件大小更大(许多参考文章,有汇编解释)
    黑马程序员:Java基础总结----JavaBean 内省
    汇编语言理解指针(指针就是汇编的间接寻址,其实就是一个简单方便的运算指令,计算完毕直接就赋值,不是从内存中去取值后赋值)
    设计项目时候的几个小标记
    SendTextMessage如何打开记事本并显示指定内容
    汇编语言---call和ret指令
    汇编语言转移指令规则汇总
    SharePoint Access Service-PowerShell
    对所有CPU寄存器的简述(16位CPU14个,32位CPU16个)
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/12459286.html
Copyright © 2011-2022 走看看