题目:

  

分析:

  其实就是两个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. struts2 相关知识

    struts2学习笔记 1.struts.properties struts.properties 是可以不要的!!!因为 struts.xml文件中 有 <constant> 这个节点, ...

  2. Qt学习之路: 国际化(上)

      原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://devbean.blog.51cto.com/448512/244689 2D ...

  3. Servlet配置文件

    <url-pattern>/servlet/demo</url-pattern> 1.以 / 开头, /代表工程路径:(必须要加 / ) 2.以 * 开头,必须加后缀名 /* ...

  4. ubuntu 12.04 编译安装 nginx

    下载源码包 nginx 地址:http://nginx.org/en/download.html 编译前先安装两个包: 直接编译安装会碰到缺少pcre等问题,这时候只要到再安装两个包就ok sudo ...

  5. webservice未能加载文件或程序集“**.DLL”或它的某一个依赖项。

    方法1.C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files先删除这个下面所有的文件,然后把bin里面的引用的dl ...

  6. oracle 11g 报错记录

    1.ORA-01034: ORACLE not available sqlplus "sys/password as sysdba" 2.ORA-00119: invalid sp ...

  7. 开源 android

    Android经典的开源项目其实非常多,但是国内的博客总是拿着N年前的一篇复制来复制去,实在是不利于新手学习.今天爬爬把自己熟悉的一些开源项目整理起来,希望能对Android开发同学们有所帮助.另外, ...

  8. SSO单点登录之数据同步

    完成单点登录,我们便可以通过只登录一个账号,来访问不同系统,然而会遇到以下问题. 1. 通过A站登录的用户访问B站,在B站并没有真实用户,此时如果在B站新建用户,则可能造成用户信息不全,或者数据冲突等 ...

  9. java csv - 读写及其操作.

    今天帮同学处理数据, 主要是从1w多条记录中随机获取8k条, 然后再从8k条记录中随机获取2k条记录. 最后将2k条记录中随机分成10组,使得每组的记录都不重复. 下面将我的代码都贴上来, 好以后处理 ...

  10. doj常用包

    dojo.raise               抛出一个异常 dojo.errorToString将异常转换为字符串 dojo.render      系统环境对象 dojo.hostenv. ...