题意

有一个队列,每个人有一个愤怒值D,如果他是第K个上场,不开心指数就为(K-1)*D。但是边上有一个小黑屋(一个FILO堆栈),可以一定程度上调整上场程序,求一种安排上场方案使得所有人的不开心指数和最小。

思路

非常好的一道区间DP题,涨了姿势了^.^

这道题困扰我的地方就在于怎么处理进堆出堆的那些情况,最后没办法网上看了题解,才想起这样一个美妙的性质:进栈出栈满足括号匹配性质!

关于括号匹配性质(即括号定理)是《算法导论》在深度优先搜索中讨论到的性质,实际上因为深度优先搜索就是栈的应用所以进出栈就满足括号定理。


括号定理:(我们用进出栈的方式描述)设d[i]、d[j]表示第i和第j个元素的进栈时间,f[i]、f[j]表示第i和第j个元素的出栈时间,则下面三种情况有且仅有一种发生:

①区间[ d[i] ,  f[i] ]和[ d[j] ,  f[j] ]完全不相交,即 () () 这种情况;

②区间[ d[i] ,  f[i] ]完全包含[ d[j] ,  f[j] ],此时表示i比j先进栈,即 ( () ) 这种情况;

③区间[ d[i] ,  f[i] ]完全包含于[ d[j] ,  f[j] ],此时表示j比i先进栈,也是 ( () ) 这种情况;


所以这里我们就发现其实这是一道区间DP:

我们设dp[i][j]表示从第i个人到第j个人这段区间的最小花费(只考虑这j-i+1个人,不需要考虑前面有多少人)。那么对于dp[i][j]的第i个人,就有可能第1个上场,也可以最后上场。考虑第k个上场,即在i+1之后的k-1个人是率先上场的,那么就出现了一个子问题 dp[i+1][k]表示在第i个人之前上场的;对于第i个人,由于是第k个上场的,那么愤怒值便是val[i]*(k-1);其余的人是排在第k+1个之后出场的,也就是一个子问题dp[k+1][j],对于这个区间的人,由于排在第k+1个之后,所以整体愤怒值要加上k*( sigma(val[k+1...j]) )

代码

[cpp]
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#define MID(x,y) ((x+y)/2)
#define MEM(a,b) memset(a,b,sizeof(a))
#define REP(i, begin, end) for (int i = begin; i <= end; i ++)
using namespace std;

int dp[105][105], D[105], sum[105];

int main(){
int t;
scanf("%d", &t);
for (int ca = 1; ca <= t; ca ++){
int n;
scanf("%d", &n);
sum[0] = 0;
for (int i = 0; i <= n; i ++){
for (int j = 0; j <= n; j ++){
if (j <= i) dp[i][j] = 0;
else dp[i][j] = 0x3fffffff;
}
}
for (int i = 1; i <= n; i ++){
scanf("%d", &D[i]);
sum[i] = sum[i-1] + D[i];
}
for (int len = 1; len < n; ++ len){
for (int i = 1; i + len <= n; i ++){
int j = i + len;
for (int k = i; k <= j; k ++){
dp[i][j] = min(dp[i][j], dp[i+1][k]+(k-i)*D[i]+dp[k+1][j]+(k-i+1)*(sum[j]-sum[k]));
}
}
}
printf("Case #%d: %d\n", ca, dp[1][n]);
}
return 0;
}
[/cpp]

HDU 4283 You Are the One ★(进出栈的括号匹配性质:区间DP)的更多相关文章

  1. STL-stack和顺序栈实现括号匹配

    2018-11-11-14:28:31 1.顺序栈 下面是我用数组实现的顺序栈,包含的函数有出入栈,查看栈顶元素,栈的大小,栈是否空等函数,当栈空间不够用时,对应的数组会自动增长. /******** ...

  2. C语言数据结构之栈:括号匹配

    括号匹配这是个很简单的题目,如果只有小括号,就模拟进栈和出栈的过程就行了: 注:输入时'@'作为结束标志 #include <stdio.h> int main() { freopen(& ...

  3. 利用顺序栈解决括号匹配问题(c++)-- 数据结构

    题目: 7-1 括号匹配 (30 分)   给定一串字符,不超过100个字符,可能包括括号.数字.字母.标点符号.空格,编程检查这一串字符中的( ) ,[ ],{ }是否匹配. 输入格式: 输入在一行 ...

  4. 《LeetBook》leetcode题解(20):Valid Parentheses[E]——栈解决括号匹配问题

    我现在在做一个叫<leetbook>的免费开源书项目,力求提供最易懂的中文思路,目前把解题思路都同步更新到gitbook上了,需要的同学可以去看看 书的地址:https://hk029.g ...

  5. Python面试题:使用栈处理括号匹配问题

    括号匹配是栈应用的一个经典问题, 题目 判断一个文本中的括号是否闭合, 如: text = "({[({{abc}})][{1}]})2([]){({[]})}[]", 判断所有括 ...

  6. 利用栈实现括号匹配(python语言)

    原理: 右括号总是与最近的左括号匹配 --- 栈的后进先出 从左往右遍历字符串,遇到左括号就入栈,遇到右括号时,就出栈一个元素与其配对 当栈为空时,遇到右括号,则此右括号无与之匹配的左括号 当最终右括 ...

  7. JAVA栈实例—括号匹配

    import java.util.Stack; public class test { public static void main(String[] args){ System.out.print ...

  8. 栈之括号匹配问题(java实现)

    假设表达式中只允许两种括号:().{}:正确表达顺序为:()或{}或({})或{({}{})}的形势:如{(}或(})或({)}的表达形势均不对.算法的设计思想: 出现左括弧则进栈: 出现右括弧则首先 ...

  9. Python 用栈判断括号匹配

    #!/usr/bin/python # -*- coding: UTF-8 -*- from pythonds.basic.stack import Stack def parChecker(symb ...

随机推荐

  1. xphrof出现502问题

    This is an xhprof bug and not a devel bug, but I thought I'd throw the workaround up here in case pe ...

  2. js的同步异步

    由于js没有多线程,所以处理多任务的时候,可以用异步回调来解决.js中setTimeout.setInterval.ajax(jq中可以选择同步或异步)均会开启异步.遇到异步模块,会将其推入值任务队列 ...

  3. FileOutputStream写出数据实现换行和追加写入

    FileOutputStream fos = fos = new FileOutputStream(Utils.getData(bizCtx,"strcat(getenv(HWORKDIR) ...

  4. 好用的http client库CPP REST SDK

    前言 C++中http client库本身就少,好用的就更少了,在了解微软开源的CPP REST SDK库之前,我知道的C++ http client库有libcurl(这个是C语言的),Qt的QNe ...

  5. CentOS6.5安装Qt4.8.6+QtCreator2.6.1

    工作中需要用到Qt在Linux下做开发,公司提供的电脑安装的CentOS6.2,但是为了和windows下自己使用的QT版本一直,于是也选择安装了Qt5.1.0.但是在CentOS下刚开始是无法启动, ...

  6. CSS 图片

    CSS 图片 一.圆角图片 img { border-radius: 8px; } 二.缩略图 border 属性来创建缩略图. img { border: 1px solid #ddd; borde ...

  7. 20145314郑凯杰 《Java程序设计》第1周学习总结

    20145314郑凯杰 <Java程序设计>第1周学习总结 教材学习内容总结 跟着教材的顺序开始总结我学过的内容: 1.三大平台 JAVA SE ,JAVA EE,JAVA ME 从毕向东 ...

  8. 20145328 《Java程序设计》第10周学习总结

    20145328 <Java程序设计>第10周学习总结 资料学习内容总结 网络编程 13.1 网络概述 网络编程技术是当前一种主流的编程技术,随着联网趋势的逐步增强以及网络应用程序的大量出 ...

  9. tiny4412的烧录工具minitool安装【学习笔记】

    烧录了半天,在win10下一直就是烧录不进去,但是在Ubuntuh环境却可以,找了很久终于找到了,原来在win10安装minitool驱动的时候没有注意到报了错误,错误内容是驱动的数字签名问题,后来禁 ...

  10. uboot向linux传递输出任何log信息的方法

    答案:在bootargs中加入loglevel=8即可(在进入linux的过程中会输出任何log信息)