左偏树

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

虽然题目要求比论文多了一个条件,但是……只需要求非递减就可以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. ssh复制公钥成功后仍需输入密码

    1,网上说权限问题 登录流程: 被登录机器的文件权限: //用户权限 chmod 700 /home/username //.ssh文件夹权限 chmod 700 ~/.ssh/ // ~/.ssh/ ...

  2. jquery even选择器 语法

    jquery even选择器 语法 作用::even 选择器选取每个带有偶数 index 值的元素(比如 2.4.6).index 值从 0 开始,所有第一个元素是偶数 (0).最常见的用法:与其他元 ...

  3. UVa 10603 Fill (BFS && 经典模拟倒水 && 隐式图)

    题意 : 有装满水的6升的杯子.空的3升杯子和1升杯子,3个杯子中都没有刻度.不使用道具情况下,是否可量出4升水呢? 你的任务是解决一般性的问题:设3个杯子的容量分别为a, b, c,最初只有第3个杯 ...

  4. 指定文件或文件夹直接提交到svn指定目录

    我这里先说两种方法第一种:1.先将那个目录checkout下来2.将要添加的文件或者文件夹放到这个目录中3.右击文件执行svn菜单中的add命令4.右击文件执行svn菜单中的commit命令第二种:如 ...

  5. 【转】BYV--有向图强连通分量的Tarjan算法

    转自beyond the void 的博客: https://www.byvoid.com/zhs/blog/scc-tarjan 注:红色为标注部分 [有向图强连通分量] 在有向图G中,如果两个顶点 ...

  6. B. Uniqueness

    B. Uniqueness 给定一个序列,要求删除一段连续子段,满足删掉子段后每个元素唯一 求最小子段长度 枚举起点,二分子段长度 记得先sort 再unique #include<bits/s ...

  7. linux 目录介绍

    /boot: 系统启动相关的文件,如内核.initrd,以及grub(bootloader)/dev: 设备文件 /etc:配置文件/home:用户的家目录,每一个用户的家目录通常默认为/home/U ...

  8. 无法加载程序集XXX.dll 此程序集可能是从 Web 上下载的

    错误    13    无法加载程序集 file:///D:\Documents\Downloads\kaxaml-master\kaxaml-master\packages\Prism.4.0.0. ...

  9. Oracle不完全恢复-主动恢复和incarnation/RMAN-20208/RMAN-06004

    12.3 主动恢复 主动不完全恢复是将数据库“撤回”到从前的传统方法,主要用来撤销认为修改.一般需要先判断PIT点的时间或SCN --1 重启db到mount状态 --2 用restore将所有的数据 ...

  10. 【RequestContext】关于RequestContext的一些小心得

    版权声明:随意转载,注明出处 https://blog.csdn.net/River_Continent/article/details/77511389后台传参,一直是一个比较重要的地方,如果涉及W ...