ssoj1740Matryoshka

题目描述

Matryoshkas are sets of traditional Russian wooden dolls of decreasing size placed one inside the other.A matryoshka doll can be opened to reveal a smaller figure of the same sort inside, which has, in turn, another figure inside, and so on.

Picture from Wikimedia Commons The Russian Matryoshka Museum recently exhibited a collection of similarly designed matryoshka sets, differing only in the number of nested dolls in each set. Unfortunately,some over-zealous (and obviously unsupervised) children separated these sets, placing all the individual dolls in a row. There are n dolls in the row, each with an integer size. You need to reassemble the matryoshka sets,knowing neither the number of sets nor the number of dolls in each set. You know only that every complete set consists of dolls with consecutive sizes from 1 to some number m, which may vary between the different sets.When reassembling the sets, you must follow these rules:

u        You can put a doll or a nested group of dolls only inside a larger doll.

u        You can combine two groups of dolls only if they are adjacent in the row.

u        Once a doll becomes a member of a group, it cannot be transferred to another group or permanently separated from the group. It can be temporarily separated only when combining two groups.

Your time is valuable, and you want to do this reassembly process as quickly as possible. The only time-consuming part of this task is opening and subsequently closing a doll, so you want to minimize how often you do this. For example, the minimum number of openings (and subsequent closings) when combining group [1, 2, 6] with the group [4] is two, since you have to open the dolls with sizes 6 and 4.

When combining group [1, 2, 5] with the group [3, 4], you need to perform three openings.

Write a program to calculate the minimum number of openings required to combine all disassembled matryoshka sets.


 

输入

The input consists of a single test case. A test case consists of two lines.

The first line contains one integer n (1 <= n <= 500) representing the number of individual dolls in the row.

The second line contains n positive integers specifying the sizes of the dolls in the order they appear in the row. Each size is between 1 and 500 inclusive.

输出

Display the minimum number of openings required when reassembling the matryoshka sets. If reassembling cannot be done (some of the kids might have been excessively zealous and taken some dolls),display the word impossible.

样例输入

【Sample Input 1】 71 2 1 2 4 3 3【Sample Input 2】 71 2 3 2 4 1 3

样例输出

【Sample Output 1】impossible【Sample Output 2】7

提示


#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn=502;
const int inf=100005;
int n,a[maxn],f[maxn][maxn],g[maxn],tmp[maxn],cst[maxn][maxn],res[maxn][maxn],mn[maxn][maxn],mx[maxn][maxn];
inline int get(){
    char c;while(!isdigit(c=getchar()));
    int v=c-48;while(isdigit(c=getchar()))v=v*10+c-48;
    return v; 
}
int main(){
    memset(mx,0,sizeof(mx));
    memset(f,0,sizeof(f));
    n=get();
    for(int i=1;i<=n;++i)a[i]=get();
    for(int i=1;i<=n;++i)
      for(int j=i;j<=n;++j){
        memset(tmp,0,sizeof(tmp));
        cst[i][j]=inf;res[i][j]=1;
        bool flag=0;
        for(int t=i;t<=j;++t) {++tmp[a[t]];if(tmp[a[t]]>1)flag=1;}
        if(flag)continue;
        cst[i][j]=0;res[i][j]=0;
        int k=1;
        while(tmp[k]==0)++k;
        if(k>1)res[i][j]=1;
        mn[i][j]=k;
        for(int t=1;t<=n;++t){
             cst[i][j]+=tmp[t];
             if(tmp[t] && t>1 && !tmp[t-1])res[i][j]=1;
        }
      }
    for(int i=1;i<=n;++i)
      for(int j=1;j<=n;++j)
        for(int k=1;k<=j;++k) if(a[k]>=i)++mx[j][i];
    for(int i=1;i<=n;++i){
        g[i]=inf;
        for(int j=i+1;j<=n;++j)f[i][j]=inf;
    }
    for(int i=2;i<=n;++i)
      for(int j=1;j+i-1<=n;++j)
        if(cst[j][j+i-1]!=inf)for(int k=j;k<j+i-1;++k){
            int mxx=max(mn[j][k],mn[k+1][j+i-1]);
            f[j][j+i-1]=min(f[j][j+i-1],f[j][k]+f[k+1][j+i-1]+mx[j+i-1][mxx]-mx[j-1][mxx]);
        }
    g[0]=0;
    for(int j=1;j<=n;++j)
        for(int i=0;i<j;++i)
            if(res[i+1][j]==0)g[j]=min(g[j],g[i]+f[i+1][j]);
    if(g[n]==inf)printf("Impossible\n");
    else printf("%d\n",g[n]);
    return 0;
}

思路:f[ i ][ j ]表示合并i-j所需的最小代价,g[ i ]表示合并前i个套娃所需的最小代价。

            f[ i ][ j ]=min(f[ i ][ k ]+f[ k+1 ][ j ]+www);

            www怎么求呢

            www即合并i~k和k+1~j所需代价(打开的套娃数),发现二者的min的较大者及其以上都要打开,而min的较小者可以看成一个整体放入。我们用mx[ n ][ m ]记录前n个套娃中比m大的有多少个,所以www=mx[ j ][ max(min,min)] - mx[ i-1 ][ max ( min , min ) ]。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Postman是一款常用的API开发和测试工具,可以用于发送HTTP请求并查看响应结果。在Postman中,可以通过Authorization界面来设置请求的认证方式。 以下是使用Postman的Authorization界面进行认证的步骤: 1. 打开Postman应用程序,并创建一个新的请求。 2. 在请求的URL栏中输入需要发送请求的URL地址。 3. 点击右侧的"Authorization"选项卡,进入认证设置界面。 4. 在认证设置界面中,选择合适的认证类型。根据提供的引用内容,可以选择"OAuth 2.0"认证类型。 5. 在"OAuth 2.0"认证类型下,填写相应的认证参数。根据提供的引用内容,需要填写"Authorization URL"和"Access Token URL"。 - 在"Authorization URL"中,填写引用中提供的URL地址:http://localhost:8090/auth/oauth/authorize?client_id=ssoj-pc&response_type=token - 在"Access Token URL"中,填写引用中提供的URL地址:http://localhost:8080/oauth/token?code=6s9qUj&grant_type=authorization_code&redirect_uri=http://www.mayikt.com/callback&scope=all 6. 根据需要,填写其他相关的认证参数,例如"Client ID"、"Client Secret"等。 7. 点击"Get New Access Token"按钮,开始进行认证流程。 8. 根据认证流程的要求,可能需要输入用户名和密码等信息。 9. 完成认证流程后,会在界面上显示获取到的Access Token信息。 10. 点击"Use Token"按钮,将Access Token添加到请求的Header中。 11. 完成认证设置后,可以点击"Send"按钮发送请求,并查看响应结果。 请注意,以上步骤仅为示例,实际使用时需要根据具体的认证方式和参数进行设置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值