题意

有一个队列,每个人有一个愤怒值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. IOS中程序如何进行推送消息(本地推送,远程推送)2(下)

    内容中包含 base64string 图片造成字符过多,拒绝显示

  2. SQLAlchemy-Utils,提供choice功能

    SQLAlchemy操作数据库建表时,无法像Django一样提供choice方法,我们开头导入SQLAlchemy-Utils来为我们提供这个功能 pip3 install sqlalchemy-ut ...

  3. PHP实现excel导出

    首先去下载PHPExcel类,地址http://phpexcel.codeplex.com/ 方法如下第一步引入这个扩展类 Vendor('PHPExcel'); 第二部就是方法了,下面简单的实现方法 ...

  4. JVM类加载机制(转)

    原文出自:http://www.cnblogs.com/ityouknow/p/5603287.html 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运 ...

  5. ABP官方文档翻译 1.2 N层架构

    N层架构 介绍 ABP架构 其他(通用) 领域层 应用层 基础设施层 网络和展现层 其他 总结 介绍 应用程序代码库的分层架构是被广泛认可的可以减少程序复杂度.提高代码复用率的技术.为了实现分层架构, ...

  6. Storm完整例子

    import backtype.storm.spout.SpoutOutputCollector; import backtype.storm.task.TopologyContext; import ...

  7. RESTful风格与RESTful Api

    REST(representational state transfer)(表述性状态转移),词汇解析: 1.representational 表述性:指资源以用各种形式来表述,包括 XML.JSON ...

  8. 20145329 《JAVA程序设计》实验三总结

    实验日期:2016.4.12 实验时间:15:30~17:30 实验序号:实验三 实验名称: 敏捷开发与XP实践 实验目的与要求: XP基础 XP核心实践 相关工具 实验内容 1.使用git托管代码 ...

  9. 20135302魏静静——linux课程第八周实验及总结

    linux课程第八周实验及总结 实验及学习总结 1. 进程切换在内核中的实现 linux中进程切换是很常见的一个操作,而这个操作是在内核中实现的. 实现的时机有以下三个时机: 中断处理过程(包括时钟中 ...

  10. linux信号的介绍

    1.基本概念    中断:        中断是系统对于异步事件的响应        中断信号        中断源        现场信息        中断处理程序        中断向量表   ...