左偏树

炒鸡棒的论文《左偏树的特点及其应用》

虽然题目要求比论文多了一个条件,但是……只需要求非递减就可以AC……数据好弱……

虽然还没想明白为什么,但是应该觉得应该是这样——求非递减用大顶堆,非递增小顶堆……

这题和bzoj1367题意差不多,但是那题求的是严格递增。(bzoj找不到那道题,可能是VIP或什么原因?

严格递增的方法就是每一个数字a[i]都要减去i,这样求得的b[i]也要再加i,保证了严格递增(为什么对我就不知道了

代码比较水,因为题目数据的问题,我的代码也就钻了空子,反正ac就好了。。。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int N = ;
typedef long long ll; struct LTree {
int l, r, sz;
int key, dis;
bool operator<(const LTree lt) const {
return key < lt.key;
}
} tr[N];
int cnt_tr; int NewTree(int k) {
tr[++cnt_tr].key = k;
tr[cnt_tr].l = tr[cnt_tr].r = tr[cnt_tr].dis = ;
tr[cnt_tr].sz = ;
return cnt_tr;
} int Merge(int x, int y) {
if (!x || !y) return x + y;
if (tr[x] < tr[y]) swap(x, y);
tr[x].r = Merge(tr[x].r, y);
if (tr[tr[x].l].dis < tr[tr[x].r].dis) swap(tr[x].l, tr[x].r);
tr[x].dis = tr[tr[x].r].dis + ;
tr[x].sz = tr[tr[x].l].sz + tr[tr[x].r].sz + ;
return x;
} int Top(int x) {
return tr[x].key;
} void Pop(int &x) {
x = Merge(tr[x].l, tr[x].r);
} int a[N], root[N], num[N]; int main() {
int n;
while (~scanf("%d",&n)) {
ll sum, tmp, ans;
cnt_tr = sum = tmp = ;
for (int i = ; i < n; ++i) {
scanf("%d", a+i);
sum += a[i];
}
int cnt = ;
for (int i = ; i < n; ++i) {
root[++cnt] = NewTree(a[i]);
num[cnt] = ;
while (cnt > && Top(root[cnt]) < Top(root[cnt-])) {
cnt--;
root[cnt] = Merge(root[cnt], root[cnt+]);
num[cnt] += num[cnt+];
while (tr[root[cnt]].sz* > num[cnt]+) Pop(root[cnt]);
}
}
int px = ;
for (int i = ; i <= cnt; ++i)
for (int j = , x = Top(root[i]); j < num[i]; ++j)
tmp += abs(a[px++]-x);
ans = tmp; printf("%lld\n", ans);
}
return ;
}

----

考虑dp,dp[i][j]表示前i个数,最后一个数是j的最小花费

dp方程:dp[i][j]=min(dp[i-1][k], k≤j) + abs(a[i]-j)

j的范围1e9,是因为对于每一个i来说,当最优解的时候j一定是a数列中的数,所以只需枚举a数列中的值就可以了。

容易想到dp[i-1][k]就不需要另外一层循环就了,同时可以使用滚动数组(不使用明显也够

上面求的是不减,求不增把数组到倒过来就可以了。(懒,没写。。

时间复杂度O(n^2),比上面左偏树明显慢了不少。

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std;
const int N = ;
const int INF = 0x5f5f5f5f; int dp[N][N];
int a[N], b[N];
int main() {
//freopen("in", "r", stdin);
int n;
scanf("%d", &n);
for (int i = ; i <= n; ++i) {
scanf("%d", a+i);
b[i] = a[i];
}
sort(b+, b++n);
int last;
for (int i = ; i <= n; ++i) {
last = INF;
for (int j = ; j <= n; ++j) {
last = min(last, dp[i-][j]);
dp[i][j] = fabs(b[j]-a[i]) + last;
}
}
int ans = INF;
for (int i = ; i <= n; ++i) {
ans = min(ans, dp[n][i]);
} printf("%d\n", ans); return ;
}

贪心

https://blog.csdn.net/lycheng1215/article/details/80089004

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std; const int maxn = 2e5 + ;
int a[maxn]; priority_queue<int>s; int main(int argc, char const *argv[])
{
int n;
scanf("%d", &n);
long long ans = ;
for(int i = ;i <= n ; i ++) {
scanf("%d", &a[i]);
//a[i] -= i;
s.push(a[i]);
if(s.top() > a[i]){
ans += s.top() - a[i];
s.pop();
s.push(a[i]);
}
}
printf("%d",ans);
return ;
}

单调递增严格就是将a[i] - i 跑 以上就行

CodeForces - 714E + POJ - 3666 (dp严格单调递增与非严格单调递增)的更多相关文章

  1. S - Making the Grade POJ - 3666 结论 将严格递减转化成非严格的

    S - Making the Grade POJ - 3666 这个题目要求把一个给定的序列变成递增或者递减序列的最小代价. 这个是一个dp,对于这个dp的定义我觉得不是很好想,如果第一次碰到的话. ...

  2. POJ 3666 DP

    题意: 思路: dp[i][j] 表示前i + 1个数变成单调且最后一个数是B[j],此时的最小成本 dp[i][j] = min(dp[i – 1][k]) + |A[i] – B[j]| [k = ...

  3. 把一个序列转换成非严格递增序列的最小花费 POJ 3666

    //把一个序列转换成非严格递增序列的最小花费 POJ 3666 //dp[i][j]:把第i个数转成第j小的数,最小花费 #include <iostream> #include < ...

  4. CodeForces 714E Sonya and Problem Wihtout a Legend(单调数列和DP的小研究)

    题意:给你n个数字,每个数字可以加减任何数字,付出变化差值的代价,求最后整个序列是严格单调递增的最小的代价. 首先我们要将这个题目进行转化,因为严格单调下是无法用下面这个dp的方法的,因此我们转化成非 ...

  5. POJ - 3666 Making the Grade(dp+离散化)

    Description A straight dirt road connects two fields on FJ's farm, but it changes elevation more tha ...

  6. Poj 3666 Making the Grade (排序+dp)

    题目链接: Poj 3666 Making the Grade 题目描述: 给出一组数,每个数代表当前位置的地面高度,问把路径修成非递增或者非递减,需要花费的最小代价? 解题思路: 对于修好的路径的每 ...

  7. 「POJ 3666」Making the Grade 题解(两种做法)

    0前言 感谢yxy童鞋的dp及暴力做法! 1 算法标签 优先队列.dp动态规划+滚动数组优化 2 题目难度 提高/提高+ CF rating:2300 3 题面 「POJ 3666」Making th ...

  8. [Codeforces 1201D]Treasure Hunting(DP)

    [Codeforces 1201D]Treasure Hunting(DP) 题面 有一个n*m的方格,方格上有k个宝藏,一个人从(1,1)出发,可以向左或者向右走,但不能向下走.给出q个列,在这些列 ...

  9. [Codeforces712D] Memory and Scores(DP+前缀和优化)(不用单调队列)

    [Codeforces712D] Memory and Scores(DP+前缀和优化)(不用单调队列) 题面 两个人玩游戏,共进行t轮,每人每轮从[-k,k]中选出一个数字,将其加到自己的总分中.已 ...

随机推荐

  1. BZOJ 4769: 超级贞鱼 逆序对 + 归并排序

    手画几下序列的变换后发现逆序对数是恒定的,故只需对第 $0$ 年求逆序对即可. 树状数组会 $TLE$ 的很惨,需要用到归并排序来求逆序对. 其实就是省掉了一个离散化的时间,估计能比树状数组快一半的时 ...

  2. Devexpress MVC GridView / CardView (持续更新)

    //获取gridview里面的combo box 显示的文本 //获取某个column在gridview的 index RightGridView.GetColumnByField("Fun ...

  3. HDU 1097 快速幂

    #include<iostream> using namespace std; long long quick(long long a,long long b,int c) { ; a=a ...

  4. [模板][快速排序&归并排序]

    不得不说,手写的快排真的好菜.(即使开了随机数...) 快速排序 #include<iostream> #include<cstdio> #include<cstring ...

  5. 【bzoj3672&&uoj7】[Noi2014]购票

    *题目描述: 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. 全国的城市构成了一棵以SZ市为根的有根树,每个城市与它的父亲用道路 ...

  6. opengl中相关的计算机图形变换矩阵之:齐次坐标 (摘编)

    模型视图变换(几何变换)矩阵: 1. 齐次坐标:两条平行线也可以相交. 在欧几里得空间中,两条平行线是无法相交的,但是在投影空间(Projective Space)这条定理就不再适用了. 比如上图中, ...

  7. wannalfy 挑战赛8 F 白云的树(树形dp)

    链接:https://www.nowcoder.com/acm/contest/57/F 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言524288K 64b ...

  8. android intent调用系统camera

    利用android的camera通常有两种方式:利用intent调用系统的camera,或者结合surfaceview实现自己定制的camera.先分别对这两种方法说明如下: 一.使用系统自配的cam ...

  9. 前台ajax传数组,后台java接收

    后端 //添加 @RequestMapping(value = "checkChoise") @ResponseBody ResultJson checkChoise(@Reque ...

  10. Js自定义数组map之bigmap

    /** * like map,but prev,curr,next and index will be given * @param {Function} cb Callback,the parame ...