题目:

  

分析:

  其实就是两个dp结合起来。第一个dp求区间[l,r]全部合并起来要用的最小次数,可以用区间[l,k]&[k+1,r]转移(l<=k<r)。第二个dp求前i个娃娃分成多个套娃组最小合并次数。这两个动态规划都是很常规的。

  我们考虑一个问题:怎样的区间才能弄成一个套娃组(即为1~p的互不相同的数)呢?其实只要保证这个区间的数互不相同且max值为len即可。

  对于要合并的两个区间[l,k]&[k+1,r],最后一步把他们合并的费用是多少呢?假设m1=min[l,k],m2=min[k+1,r],则不用打开的套娃数为这个区间中小于max(m1,m2)的数的个数。(这个也很好理解)

  然而我想不到很好的处理的方法,本题数据规模是n<=500,总感觉会超时,然而却AC了~~

代码如下:(有点恶心~~~)

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define Maxn 510
#define INF 0xfffffff int n;
int a[Maxn],mx[Maxn][Maxn],mn[Maxn][Maxn];
bool p[Maxn][Maxn];
int dp[Maxn][Maxn],f[Maxn],nt[Maxn],first[Maxn]; int mymax(int x,int y) {return x>y?x:y;}
int mymin(int x,int y) {return x<y?x:y;} struct node
{
int id,x;
};//t[Maxn]; bool cmp(node x,node y) {return x.x<y.x;} void init()
{
memset(first,,sizeof(first));
memset(p,,sizeof(p));
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
nt[i]=first[a[i]];first[a[i]]=i;
}
memset(mn,,sizeof(mn));
for(int i=;i<=n;i++) mx[i][i]=mn[i][i]=a[i],p[i][i]=;
for(int i=n;i>=;i--)
for(int j=i+;j<=n;j++)
{
mx[i][j]=mymax(mx[i][j-],a[j]);
mn[i][j]=mymin(mn[i][j-],a[j]);
if(p[i][j-]&&nt[j]<i) p[i][j]=;
}
} int ddp(int x,int y)
{
if(dp[x][y]<) return dp[x][y];
if(x==y) {dp[x][y]=;return ;}
int num;
node t[Maxn];
for(int i=x;i<=y;i++) t[i-x+].x=a[i],t[i-x+].id=i;
sort(t+,t++y-x+,cmp);
for(int i=x;i<y;i++)
{
int mm=mymax(mn[x][i],mn[i+][y]);
num=;
for(int j=;j<=y-x+;j++)
{
if(t[j].x==mm) break;
if(t[j].x<mm) num++;
}
num=y-x+-num;
dp[x][y]=mymin(dp[x][y],ddp(x,i)+ddp(i+,y)+num);
}
return dp[x][y];
} void ffind()
{
memset(dp,,sizeof(dp));
memset(f,,sizeof(f));
for(int i=;i<=n;i++)
for(int j=i;j<=n;j++)
{
if(mx[i][j]==j-i+&&p[i][j])
ddp(i,j);
}
f[]=;
for(int i=;i<=n;i++)
for(int j=;j<i;j++) if(mx[j+][i]==i-j&&p[j+][i])
{
f[i]=mymin(f[i],f[j]+dp[j+][i]);
}
if(f[n]>) printf("impossible\n");
else printf("%d\n",f[n]);
} int main()
{
while(scanf("%d",&n)!=EOF)
{
init();
ffind();
}
return ;
}

uva1579

2016-03-08 13:32:04

【UVA1579】俄罗斯套娃 Matryoshka (动态规划)的更多相关文章

  1. UVA-1579 Matryoshka (区间DP)

    题目大意:n个俄罗斯套娃,都有相应的编号,每次可将两个相邻的套娃组合成一组,每次合成只能小的放到大的里面,并且是逐层嵌套.问将这n个套娃分成若干个组,并且每组都是编号从1开始的连续序列,最少需要几步. ...

  2. 清晰明了的javascript版动态规划

    算法是一种艺术,给人感觉很不好接近,但是一旦你和ta熟络了,你就能发现这门艺术的内在是多么美妙且多变. 对于前端来说,算法也许不是最重要的,在日常工作中,几乎很少用到.所以很多人也不是很感冒. 不过呢 ...

  3. leetcode 354. 俄罗斯套娃信封问题(二维排序有关)

    题目描述 给定一些标记了宽度和高度的信封,宽度和高度以整数对形式 (w, h) 出现.当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样. 请计算最多能有 ...

  4. C#LeetCode刷题-动态规划

    动态规划篇 # 题名 刷题 通过率 难度 5 最长回文子串   22.4% 中等 10 正则表达式匹配   18.8% 困难 32 最长有效括号   23.3% 困难 44 通配符匹配   17.7% ...

  5. LeetCode刷题总结-动态规划篇

    本文总结LeetCode上有动态规划的算法题,推荐刷题总数为54道.具体考点分析如下图: 1.中心扩展法 题号:132. 分割回文串 II,难度困难 2.背包问题 题号:140. 单词拆分 II,难度 ...

  6. 【NOIP2015模拟11.5】JZOJ8月5日提高组T1 俄罗斯套娃

    [NOIP2015模拟11.5]JZOJ8月5日提高组T1 俄罗斯套娃 题目 题解 题意就是说 将1~\(n\)排列,问有多少种方案使得序列的逆序对个数小于\(k\) 很容易想到DP 设\(f[i][ ...

  7. leetcode动态规划题目总结

    Hello everyone, I am a Chinese noob programmer. I have practiced questions on leetcode.com for 2 yea ...

  8. LeetCode:动态规划

    动态规划 动态规划永远的神 这部分主要是学习了 labuladong 公众号中对于动态规划的讲解 刷了些 leetcode 题,在此做一些记录,不然没几天就忘光光了 题目 这部分内容直接上题目了,解题 ...

  9. 增强学习(三)----- MDP的动态规划解法

    上一篇我们已经说到了,增强学习的目的就是求解马尔可夫决策过程(MDP)的最优策略,使其在任意初始状态下,都能获得最大的Vπ值.(本文不考虑非马尔可夫环境和不完全可观测马尔可夫决策过程(POMDP)中的 ...

随机推荐

  1. cocos2d-x 2.1.4学习笔记之HelloWorld分析

    下面截图是HelloWorld项目下的文件夹结构 这是用python命令生成的项目,在创建过程中默认生成多个平台的程序文件. 1.“resource”文件夹 该文件夹主要用于存放游戏中需要的图片.音频 ...

  2. 关于Clone 的方法使用

    package cn.hncu.day7.clone.v1;//克隆的套路:// 第1步:重写User类的clone()方法,以供外面调用.因为外面的类无法直接调用User类父类中的clone()方法 ...

  3. oracle多表查询

    多表查询首先要避免笛卡尔集,要避免笛卡尔集,那么查询条件不得少于表的个数-1. 1.显示雇员名,雇员工资以及雇员所在的部门: 2.显示部门号为10的部门名.员工名和工资: 3.显示各个雇员的姓名,工资 ...

  4. 多目标遗传算法 ------ NSGA-II (部分源码解析) 快速排序代码 sort.c

    /* Routines for randomized recursive quick-sort */ # include <stdio.h> # include <stdlib.h& ...

  5. JDK和JVM

    JDK: JDK包含的基本组件包括: javac – 编译器,将源程序转成字节码 jar – 打包工具,将相关的类文件打包成一个文件 javadoc – 文档生成器,从源码注释中提取文档 jdb – ...

  6. xml--小结③DTD的基本语法(看懂即可)

    四.DTD的基本语法(看懂即可)1.DTD:Document Type Definition2.作用:约束XML的书写规范.3.DTD文件保存到磁盘时,必须使用UTF-8编码 4.如何引入外部的DTD ...

  7. U3D 收藏一个飞机随机运动的方法

    文章转载:http://www.manew.com/thread-43578-1-1.html 前面的学习中已经涉及到了随机运动,这一篇主要还是前面的随机运动的改进,不废话直接上效果图吧,对比前面的随 ...

  8. [IO] C# FileOperateHelper文件操作类与源码下载

    主要功能如下所示 源码预览 /// <summary> /// 类说明:Assistant /// 编 码 人:苏飞 /// 联系方式:361983679 /// 更新网站:[url]ht ...

  9. 使用Navicat for Oracle 出现的错误

    错误提示: 意思是不能创建oci环境我们需要对 Navicat for Oracle 做一下配置依此选择 Tools -> Miscellaneous -> OCI OCI library ...

  10. play app to war

    project/Build.scala import sbt._ import Keys._ import play.Play.autoImport._ import PlayKeys._ impor ...