HDU 2838 (DP+树状数组维护带权排序)
Reference: http://blog.csdn.net/me4546/article/details/6333225
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2838
题目大意:每头牛有个愤怒值,每次交换相邻两个数进行升序排序,$cost=val_{1}+val_{2}$,求$\min \sum cost_{i}$
解题思路:
按输入顺序DP:
第i的值val的最小cost=当前数的逆序数个数*val+当前数的逆序数和
相当于每次只把这个val同逆序的数做交换,$\sum val_{1}=rev*val$ , $\sum val_{2}=\sum rev$
无后效性原则体现在,当前计算的cost只于前面的数有关,而且对顺序没有影响(逆序数随你怎么排了)
求逆序数个数和逆序数和都可以通过树状数组在$O(logn)$内完成
维护逆序数个数
树状数组对于每个val,$update(val,1)$,即每个val点的值是1
这样$rev=i-getIndex(val)$
原理是,树状数组是按从小到大维护的,输入顺序i(从1开始)-前面数个数(包含自身)=本来应该在后面,却跑到前面数的个数
维护逆序数和
本题的一个trick就是val不可重,所以$update(val,val)$ ,即每个val点的值是val
这样$\sum=getSum(n)-getSum(val)$,即整个序列已经更新的值和(i~n此时都是0)-当前值前面的和=逆序数和
代码
#include "cstdio"
#include "map"
#include "cstring"
#include "algorithm"
using namespace std;
#define LL long long
#define maxn 100005
LL sum[maxn],index[maxn];
int val,n;
int lowbit(int x) {return x&(-x);}
LL getSum(int x)
{
LL ret=;
while(x>)
{
ret+=sum[x];
x-=lowbit(x);
}
return ret;
}
LL getIndex(int x)
{
LL ret=;
while(x>)
{
ret+=index[x];
x-=lowbit(x);
}
return ret;
}
void update(int x,int s,int idx)
{
while(x<=n)
{
sum[x]+=s;
index[x]+=idx;
x+=lowbit(x);
}
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d",&n)!=EOF)
{
memset(sum,,sizeof(sum));
memset(index,,sizeof(index));
LL ans=;
for(int i=;i<=n;i++)
{
scanf("%d",&val);
update(val,val,);
LL rev=i-getIndex(val);
if(rev==) continue;
LL sum=getSum(n)-getSum(val);
ans+=(rev*val+sum);
}
printf("%I64d\n",ans);
}
}
HDU 2838 (DP+树状数组维护带权排序)的更多相关文章
- [poj3378] Crazy Thairs (DP + 树状数组维护 + 高精度)
树状数组维护DP + 高精度 Description These days, Sempr is crazed on one problem named Crazy Thair. Given N (1 ...
- P1020 导弹拦截 dp 树状数组维护最长升序列
题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ...
- HDU 2838 (树状数组求逆序数)
题意: 给你N个排列不规则的数(1~N),任务是把它从小到大排好,每次仅仅能交换相邻两个数,交换一次的代价为两数之和.求最小代价 思路:对于当前数X.我们如果知道前面比它大的数有多少,如果为K,那么有 ...
- CodeForces 1058 F Putting Boxes Together 树状数组,带权中位数
Putting Boxes Together 题意: 现在有n个物品,第i个物品他的位置在a[i],他的重量为w[i].每一个物品移动一步的代价为他的w[i].目前有2种操作: 1. x y 将第x的 ...
- HDU 5869 Different GCD Subarray Query (GCD种类预处理+树状数组维护)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5869 问你l~r之间的连续序列的gcd种类. 首先固定右端点,预处理gcd不同尽量靠右的位置(此时gc ...
- 树形DP+树状数组 HDU 5877 Weak Pair
//树形DP+树状数组 HDU 5877 Weak Pair // 思路:用树状数组每次加k/a[i],每个节点ans+=Sum(a[i]) 表示每次加大于等于a[i]的值 // 这道题要离散化 #i ...
- HDU 5489 Removed Interval DP 树状数组
题意: 给一个长度为\(N\)的序列,要删除一段长为\(L\)的连续子序列,问所能得到的最长的\(LIS\)的长度. 分析: 设\(f(i)\)表示以\(a_i\)结尾的\(LIS\)的长度,设\(g ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ's Salesman 【离散化+树状数组维护区间最大值】
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/O ...
- bzoj 3594: [Scoi2014]方伯伯的玉米田 dp树状数组优化
3594: [Scoi2014]方伯伯的玉米田 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 314 Solved: 132[Submit][Sta ...
随机推荐
- hdu 2020
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2020 思路:优先队列水过priority_queue #include <cstdio> ...
- ajax实例1
前台: function getDetail(index){ $.post("<%=request.getContextPath() %>/member/dbcenter!get ...
- MVC部分视图(Partial View)
分部视图,也就是整体视图的一部分.单个视图页面展示在整体页面之上,使用步骤如下 1.创建视图数据也就是viewmodel public class FooterViewModel { public s ...
- 【翻译十三】java-并发之饥饿与活锁
Starvation and Livelock Starvation and livelock are much less common a problem than deadlock, but ar ...
- OCJP(1Z0-851) 模拟题分析(一)11
Exam : 1Z0-851 Java Standard Edition 6 Programmer Certified Professional Exam 以下分析全都是我自己分析或者参考网上的,定有 ...
- js继承的概念
js里常用的如下两种继承方式: 原型链继承(对象间的继承) 类式继承(构造函数间的继承) 由于js不像java那样是真正面向对象的语言,js是基于对象的,它没有类的概念.所以,要想实现继承,可以用js ...
- .NET Nancy 详解(二) 简易路由实现
继续上面的简易版本,有意思的点剩下便是路由实现了. 路由注册 首先,来看一下基本的路由注册过程. public FakeNancyModuleWithoutBasePath() { Delete[&q ...
- 单图上传预览(uploadpreview )
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 面试题之【打印1到最大的N位数】
题目描述:给定一个数字N,打印从1到最大的N位数. 看起来像是很简单的问题(虽然实际也不是很难...)我们很容易写出这样的代码: #include<iostream> #include&l ...
- Java 类装载器
类装载器 基本概念: 顾名思义,类加载器(class loader)用来把Java 类动态的加载到 Java 虚拟机中.也就是说当程序需要某个类时,类加载器就把这个类的二进行加入到虚拟机中. 类加载器 ...