题意

有一个队列,每个人有一个愤怒值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. mysql数据库从删库到跑路之mysql基础

    一 数据库是什么 之前所学,数据要永久保存,比如用户注册的用户信息,都是保存于文件中,而文件只能存在于某一台机器上. 如果我们不考虑从文件中读取数据的效率问题,并且假设我们的程序所有的组件都运行在一台 ...

  2. Django:学习笔记(9)——用户身份认证

    Django:学习笔记(9)——用户身份认证 User

  3. Java设计原则—迪米特法则(转)

    定义: 迪米特法则(Law of Demeter,LoD)也称为最少知识原则(Least Knowledge Principle,LKP). 一个对象应该对其他对象有最少的了解.通俗地讲,一个类应该对 ...

  4. hdu4763 Theme Section

    地址:http://acm.hdu.edu.cn/showproblem.php?pid=4763 题目: Theme Section Time Limit: 2000/1000 MS (Java/O ...

  5. LeetCode 902. Numbers At Most N Given Digit Set

    应该是常数 N的位数时间级别 我的这个方法超时很严重...但是特此记录 费劲巴拉写的... 超时: int atMostNGivenDigitSet(char** D, int DSize, int ...

  6. visual studio开发工具的C#主流控件属性一览表

    visual studio开发工具的C#主流控件属性一览表 详细的介绍了各控制属性的详细中文介绍 C#控件及常用设计整理 1.窗体 1.常用属性 (1)Name属性:用来获取或设置窗体的名称,在应用程 ...

  7. Lua 可控下标数组遍历

    , , , , , , , , , , , } , , } local j = 1 while i <= #aaa do if bbb[j] == aaa[i] then -- 如果 b下标元素 ...

  8. 简单封装get和jsonp

    /** * 向服务器发送GET请求. *  * @param {type} url * @param {type} async 是否异步调用 * @param {type} fnCallback 回调 ...

  9. WCF可靠性会话之服务分流

    可靠性绘画答条件: (1)服务绑定支持可靠性绘画:特别是netTcpBinding.wsHttpBinding及wsDualHttpBinding. wsDualHtttpBinding可靠性绘画始终 ...

  10. [Linux 004]——用户和用户组以及 Linux 权限管理(二)

    到权限了.前面讲到了 Linux 中的用户和用户主管理,其实它们的本质(或者用户和用户组出现的初衷)都是方便权限管理.权限管理对于计算机的重要性不言而喻,权限让每个用户能够安安心心的使用计算机,而不用 ...