题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3872

  题意:有n个龙珠按顺序放在一列,每个龙珠有一个type和一个权值,要求你把这n个龙珠分成k个段,每段的权值是这段中的最大的权值,使得最后的权值之和最小。但是现在有个要求,分的段中,龙珠的type不能和最右边的相等。

  容易想到是一个DP:f[i]=Min{f[j]+Min(j,i) | j是满足要求的点}。直接搞的话O(n^2),显然超时了。但是可以发现,这个Min(j,i)是有分段性的,因此我们可以维护一个单调递减的栈,那么只要求栈中的元素就可以了,因为只有这些元素有效。这里还要求最小值,需要维护两课线段树,一颗是维护f[i]最小,还有一棵是f[j]+min(相对应的栈中的元素)。此题细节比较多,容易出错>,<,,,,也可能是我很久没刷题,残了T^T

 //STATUS:C++_AC_1796MS_8848KB
#include <functional>
#include <algorithm>
#include <iostream>
//#include <ext/rope>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <numeric>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <string>
#include <vector>
#include <bitset>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,102400000")
//using namespace __gnu_cxx;
//define
#define pii pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define PI acos(-1.0)
//typedef
typedef __int64 LL;
typedef unsigned __int64 ULL;
//const
const int N=;
const int INF=0x3f3f3f3f;
const int MOD=,STA=;
const LL LNF=1LL<<;
const double EPS=1e-;
const double OO=1e15;
const int dx[]={-,,,};
const int dy[]={,,,-};
const int day[]={,,,,,,,,,,,,};
//Daily Use ...
inline int sign(double x){return (x>EPS)-(x<-EPS);}
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> inline T lcm(T a,T b,T d){return a/d*b;}
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}
template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}
template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}
template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}
//End LL low[N<<][],f[N];
int l[N],la[N],q[N][],type[N],eng[N];
int T,n; void update(int l,int r,int rt,int w,LL val,int flag)
{
if(l==r){
low[rt][flag]=val;
return;
}
int mid=(l+r)>>;
if(w<=mid)update(lson,w,val,flag);
else update(rson,w,val,flag);
low[rt][flag]=Min(low[rt<<][flag],low[rt<<|][flag]);
} LL query(int l,int r,int rt,int L,int R,int flag)
{
if(L<=l && r<=R){
return low[rt][flag];
}
int mid=(l+r)>>;
LL ret=LNF;
if(L<=mid)ret=Min(ret,query(lson,L,R,flag));
if(R>mid)ret=Min(ret,query(rson,L,R,flag));
return ret;
} int binary(int l,int r,int tar)
{
int mid;
while(l<r){
mid=(l+r)>>;
if(q[mid][]<tar)l=mid+;
else r=mid;
}
return l;
} int main()
{
// freopen("in.txt","r",stdin);
int i,j,t,L,R,top;
LL lowf;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
mem(la,);
for(i=;i<=n;i++){
scanf("%d",&type[i]);
l[i]=la[type[i]];
la[type[i]]=i;
}
for(i=;i<=n;i++){
scanf("%d",&eng[i]);
} mem(low,INF);mem(f,INF);f[]=;
update(,n+,,,,);
q[top=][]=;q[top][]=INF;
for(i=;i<=n;i++){
while(q[top][]<=eng[i]){
update(,n+,,q[top-][],LNF,);
top--;
}
q[++top][]=i;q[top][]=eng[i];
t=q[top-][];
lowf=query(,n+,,t,i-,);
update(,n+,,t,lowf+eng[i],); L=binary(,top+,l[i]);
f[i]=query(,n+,,q[L][],i,);
if(l[i]<q[L][]){
lowf=query(,n+,,l[i],q[L][]-,);
f[i]=Min(f[i],lowf+q[L][]);
}
update(,n+,,i,f[i],);
} printf("%I64d\n",f[n]);
}
return ;
}

HDU-3872 Dragon Ball 线段树+DP的更多相关文章

  1. HDU 4362 Dragon Ball 线段树

    #include <cstdio> #include <cstring> #include <cmath> #include <queue> #incl ...

  2. HDU 5125 magic balls(线段树+DP)

    magic balls Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  3. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  4. HDU.1556 Color the ball (线段树 区间更新 单点查询)

    HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...

  5. Tsinsen A1219. 采矿(陈许旻) (树链剖分,线段树 + DP)

    [题目链接] http://www.tsinsen.com/A1219 [题意] 给定一棵树,a[u][i]代表u结点分配i人的收益,可以随时改变a[u],查询(u,v)代表在u子树的所有节点,在u- ...

  6. hdu 5700区间交(线段树)

    区间交 Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submiss ...

  7. Snacks HDU 5692 dfs序列+线段树

    Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...

  8. HDU 1556 Color the ball(线段树区间更新)

    Color the ball 我真的该认真的复习一下以前没懂的知识了,今天看了一下线段树,以前只会用模板,现在看懂了之后,发现还有这么多巧妙的地方,好厉害啊 所以就应该尽量搞懂 弄明白每个知识点 [题 ...

  9. HDU 4362 Dragon Ball 贪心DP

    Dragon Ball Problem Description   Sean has got a Treasure map which shows when and where the dragon ...

随机推荐

  1. 重新安装sqlyog时备份数据库链接列表的方法

    一般在本机C:\Documents and Settings\Administrator\Application Data\SQLyog这个目录下有个sqlyog.ini文件.把这个文件备份一下就ok ...

  2. [POJ3264]Balanced Lineup(RMQ, ST算法)

    题目链接:http://poj.org/problem?id=3264 典型RMQ,这道题被我鞭尸了三遍也是醉了…这回用新学的st算法. st算法本身是一个区间dp,利用的性质就是相邻两个区间的最值的 ...

  3. 《OD大数据实战》HDFS入门实例

    一.环境搭建 1.  下载安装配置 <OD大数据实战>Hadoop伪分布式环境搭建 2. Hadoop配置信息 1)${HADOOP_HOME}/libexec:存储hadoop的默认环境 ...

  4. 《OD学hive》第五周0723

    https://cwiki.apache.org/confluence/display/Hive/LanguageManual 一.创建表 create table student(id int, n ...

  5. 【温故知新】c#异步编程模型(APM)--使用委托进行异步编程

    当我们用到C#类许多耗时的函数XXX时,总会存在同名的类似BeginXXX,EndXXX这样的函数. 例如Stream抽象类的Read函数就有 public abstract int Read(byt ...

  6. Android实现ExpandableTextView可扩展TextView

    介绍 在应用开发中,总会遇到一些类似于公告,说明等长文本的TextView,但是为了排版美观等因素,我们通常是要隐藏后半部的文本,只显示部分文字,然后在尾部会提供用户一个扩展/收缩的按钮,使得文本框可 ...

  7. 如何将开源项目部分代码作为private放在github上?

    很多时候,你的一些项目本身都是开源的,但是基于该开源项目,你可能做了部分更有价值的工作,或者由于其他原因,你不希望将这部分代码放到public上,那么有以下简单方法: 1. 创建一个private b ...

  8. BZOJ3306: 树

    3306: 树 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 311  Solved: 86[Submit][Status] Description ...

  9. 自己实现内存操作函数memset(),memcmp(),memcpy(),memmove()

    1.memset()内存设置函数(初始化) void *my_memset(void* dest, int c, size_t count) { assert(dest != NULL); char  ...

  10. HDU 5327 Olympiad (水题)

    题意:beautiful数字定义为该数字中的十进制形式每一位都不同,给一个区间[L,R],求该区间中有多少个beautiful数字. 思路:数字不大,直接暴力预处理,再统计区间[1,i]有多少个,用c ...