题目链接: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. 将Android Studio工程导入到Eclipse中

    1.前言 studio项目中src/main/java目录里面的代码对应的是eclispe项目中的src目录中的代码. 而studio中src目录里面包括整个项目的所有代码包括资源文件和xml. 2. ...

  2. C语言输出当前日期和时间

    #include <stdio.h> #include <time.h> char* asctime2(const struct tm *timeptr) { static c ...

  3. opencv实现KNN手写数字的识别

    人工智能是当下很热门的话题,手写识别是一个典型的应用.为了进一步了解这个领域,我阅读了大量的论文,并借助opencv完成了对28x28的数字图片(预处理后的二值图像)的识别任务. 预处理一张图片: 首 ...

  4. Android EditText截获与监听输入事件

      Android EditText截获与监听输入事件共有2种方法: 1.第一种方法:使用setOnKeyListener(),不过这种方式只能监听硬键盘事件. edittext.setOnKeyLi ...

  5. PHPStorm/webstorm tips

    phpstorm对于使用PHP开发web的人员来说,是一个非常不错的编辑开发IDE,以前用过sublime,但是相比于storm,sublime在浏览legacy代码,类代码编辑方面明显要逊色不少.同 ...

  6. UVa 10791 Minimum Sum LCM【唯一分解定理】

    题意:给出n,求至少两个正整数,使得它们的最小公倍数为n,且这些整数的和最小 看的紫书--- 用唯一分解定理,n=(a1)^p1*(a2)^p2---*(ak)^pk,当每一个(ak)^pk作为一个单 ...

  7. 13.Object-C--浅谈Foundation框架常用的结构体

    ------- android培训.iOS培训.期待与您交流! ---------- 昨天学习了Foundation框架中常用的结构体,下面我简单的总结一下,如果错误麻烦请留言指正,谢谢! Found ...

  8. 以一个上传文件的例子来说 DistributedFileSystem

    public class UploadAndDown { public static void main(String[] args) { UploadAndDown uploadAndDown = ...

  9. codevs 1138 聪明的质监员

    二分+前缀和. #include<iostream> #include<cstdio> #include<cstring> #include<cmath> ...

  10. ios中get,post和解压缩用法

    一. 网络概念 1. 在Linux系统上,运行的Web服务器的名字叫做Apache 2. 所有的http访问都是基于html或者相关的文件,例如:php,asp,jsp,asp.net 这些文件最终都 ...