HDU 4283 You Are the One ★(进出栈的括号匹配性质:区间DP)
题意
有一个队列,每个人有一个愤怒值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)的更多相关文章
- STL-stack和顺序栈实现括号匹配
2018-11-11-14:28:31 1.顺序栈 下面是我用数组实现的顺序栈,包含的函数有出入栈,查看栈顶元素,栈的大小,栈是否空等函数,当栈空间不够用时,对应的数组会自动增长. /******** ...
- C语言数据结构之栈:括号匹配
括号匹配这是个很简单的题目,如果只有小括号,就模拟进栈和出栈的过程就行了: 注:输入时'@'作为结束标志 #include <stdio.h> int main() { freopen(& ...
- 利用顺序栈解决括号匹配问题(c++)-- 数据结构
题目: 7-1 括号匹配 (30 分) 给定一串字符,不超过100个字符,可能包括括号.数字.字母.标点符号.空格,编程检查这一串字符中的( ) ,[ ],{ }是否匹配. 输入格式: 输入在一行 ...
- 《LeetBook》leetcode题解(20):Valid Parentheses[E]——栈解决括号匹配问题
我现在在做一个叫<leetbook>的免费开源书项目,力求提供最易懂的中文思路,目前把解题思路都同步更新到gitbook上了,需要的同学可以去看看 书的地址:https://hk029.g ...
- Python面试题:使用栈处理括号匹配问题
括号匹配是栈应用的一个经典问题, 题目 判断一个文本中的括号是否闭合, 如: text = "({[({{abc}})][{1}]})2([]){({[]})}[]", 判断所有括 ...
- 利用栈实现括号匹配(python语言)
原理: 右括号总是与最近的左括号匹配 --- 栈的后进先出 从左往右遍历字符串,遇到左括号就入栈,遇到右括号时,就出栈一个元素与其配对 当栈为空时,遇到右括号,则此右括号无与之匹配的左括号 当最终右括 ...
- JAVA栈实例—括号匹配
import java.util.Stack; public class test { public static void main(String[] args){ System.out.print ...
- 栈之括号匹配问题(java实现)
假设表达式中只允许两种括号:().{}:正确表达顺序为:()或{}或({})或{({}{})}的形势:如{(}或(})或({)}的表达形势均不对.算法的设计思想: 出现左括弧则进栈: 出现右括弧则首先 ...
- Python 用栈判断括号匹配
#!/usr/bin/python # -*- coding: UTF-8 -*- from pythonds.basic.stack import Stack def parChecker(symb ...
随机推荐
- 设计模式学习(二):面向对象设计原则与UML类图
一.UML类图和面向对象设计原则简介 在学习设计模式之前,需要找我一些预备知识,主要包括UML类图和面向对象设计原则. UML类图可用于描述每一个设计模式的结构以及对模式实例进行说明,而模式结构又是设 ...
- 斩获新知——记一次reverse的实现过程
最近学习C++,在实现reverse模板函数的时候,从一个小问题开始,在对这个问题的旁敲侧击当中带起了更多疑惑,顺藤摸瓜之后,尽管没有将诸多问题完美解答,但整个过程下来却也似有所获.最初的问题从使用C ...
- Google Code Jam 2014 总结
第一次参加ACM竞赛,对自己取得的成绩还满意. Round1A: Rank: 2446 Score: 9 (没有进前1000名,只能拼下次了) Round1B: Rank: 944 Score: 42 ...
- intellij-idea+maven搭建scala环境
一 . 安装JDK 1. 下载地址: http://download.oracle.com/otn-pub/java/jdk/8u181-b13/96a7b8442fe848ef90c96a2fad6 ...
- hive报错汇总
1.需要注意的是,要在namenode(超级用户)上操作,貌似是 hive> insert into table record_partition partition(trancation_da ...
- python3_ftp文件传输
Python中的ftplib模块 Python中默认安装的ftplib模块定义了FTP类,其中函数有限,可用来实现简单的ftp客户端,用于上传或下载文件 FTP的工作流程及基本操作可参考协议RFC95 ...
- nginx之proxy、cache、upstream模块学习
nginx之proxy反向代理模块: location ^~ /proxy_path/ { root "/www/html"; 这里没必要配置 index index.html; ...
- cogs 896. 圈奶牛
★★☆ 输入文件:fc.in 输出文件:fc.out 简单对比 时间限制:1 s 内存限制:128 MB 描述 农夫约翰想要建造一个围栏用来围住他的奶牛,可是他资金匮乏.他建造的围栏必 ...
- MysQL使用一高级应用(下)
连接查询 连接查询分类如下: 表A inner join 表B:表A与表B匹配的行会出现在结果中 表A left join 表B:表A与表B匹配的行会出现在结果中,外加表A中独有的数据,未对应的数据使 ...
- 推荐一个快速了解移植uboot以及linux到新板子上的ppt教程
链接地址在此: https://elinux.org/images/2/2a/Schulz-how-to-support-new-board-u-boot-linux.pdf