首页 > 其他分享 >2022.10.20-B 排序

2022.10.20-B 排序

时间:2022-10-24 09:34:04浏览次数:93  
标签:20 200005 int LL re 操作 排序 2022.10 define

题意

一个长为 \(n\) 的排列,第 \(i\) 个位置上的数是 \(p_i\);

花费 \(a_i\) 的代价将数字 \(i\) 移到任意位置;

花费 \(b_i\) 的代价将数字 \(i\) 移到左端;

花费 \(c_i\) 的代价将数字 \(i\) 移到右端。

问将排列从小到大排序的最小花费。


思路

首先有个贪心,就是 \(b_i,c_i\) 都要与 \(a_i\) 取 \(\min\)。

对于操作 \(B\),一定是 \([1,x]\) 的数都进行操作;对于操作 \(C\),一定是 \([y,n]\) 的数进行操作。

  • 首先,如果我们要将 \(x\) 移到左边,那么 \(x\) 之前一直到 \(1\) 的数都必须要移动;

  • 其次,操作 \(B\) 的代价是 \(\le\) 操作 \(A\) 的,因此一定是选择操作 \(B\) 更优。

  • 对于操作 \(C\) 同理。

因此问题转化为:\([1,x]\) 移到左边,\([y,n]\) 移到右边,\([x+1,y-1]\) 一些不动,一些移到任意位置,要求代价最小。

我们设 \(f_i\) 表示 \(i\) 不动的最小花费(不含操作 \(C\))。

那么有转移:

\[f_i=\min_{pos[j]<pos[i]}\{f_j+\sum_{k=j+1}^{i-1} a_k\} \]

这个可以用树状数组优化。


代码

#include<bits/stdc++.h>
#define LL long long
#define max(x...) std::max({x})
#define min(x...) std::min({x})
#define FOR(i, x, y) for(int i = (x); i <= (y); i++)
#define ROF(i, x, y) for(int i = (x); i >= (y); i--)
inline int rd()
{
    int sign = 1, re = 0; char c = getchar();
    while(!isdigit(c)){if(c == '-') sign = -1; c = getchar();}
    while(isdigit(c)){re = re * 10 + (c - '0'); c = getchar();}
    return sign * re;
}
const LL INF = 1e18;
int n, p[200005];
int a[200005], b[200005], c[200005];
LL sa[200005], sb[200005], sc[200005];
LL tr[200005], f[200005];
inline int lb(int x) {return x & (-x);}
inline void add(int x, LL val)
{
    x++;
    while(x <= (n + 1))
    {
        tr[x] = min(tr[x], val);
        x += lb(x);
    }
}
inline LL query(int x)
{
    x++; LL re = INF;
    while(x)
    {
        re = min(re, tr[x]);
        x ^= lb(x);
    }
    return re;
}
signed main()
{
#ifdef ONLINE_JUDGE
    freopen("sort.in", "r", stdin);
    freopen("sort.out", "w", stdout);
#endif
    n = rd();
    FOR(i, 1, n) p[rd()] = i;
    FOR(i, 1, n) a[i] = rd(), b[i] = min(a[i], rd()), c[i] = min(a[i], rd());
    FOR(i, 1, n) sa[i] = sa[i - 1] + a[i], sb[i] = sb[i - 1] + b[i], sc[i] = sc[i - 1] + c[i], tr[i] = INF;
    tr[n + 1] = INF; add(0, 0);
    LL ans = INF;
    FOR(i, 1, n)
    {
        f[i] = min(query(p[i]) + sa[i - 1], sb[i - 1]);
        ans = min(ans, f[i] + sc[n] - sc[i]);
        add(p[i], f[i] - sa[i]);
    }
    printf("%lld", ans);
    return 0;
}

标签:20,200005,int,LL,re,操作,排序,2022.10,define
From: https://www.cnblogs.com/zuytong/p/16820423.html

相关文章

  • 2022年XX百万职工技能大赛 XX区网络安全与信息管理员比赛 经验之谈
    本次有幸参加了一次,《百万职工技能大赛XX区网络安全与信息管理员比赛》分享下个人经验: 大赛标准:个人赛以国家职业技能标准中级工及以上职业资格等级的要求为基础,适当增......
  • Week - 2022/10/17~2022/10/23 周记
    Week-2022/10/17~2022/10/23周记???-2022/10/19-Wed.-17:55大抵是一些无病呻吟。某些程度上来说这或许就是我这周的状态了吧。。CSP2022还有一周多一点了,虽然这......
  • 2022.10.21 模拟赛小结
    2022.10.21模拟赛小结目录2022.10.21模拟赛小结更好的阅读体验戳此进入赛时思路T1CodeT2CodeT3CodeT4Code正解T2CodeT3T4UPDsssmzyAK了,zpair差一点AK了,我寄了。......
  • 2022.10.19 模拟赛小结
    2022.10.19模拟赛小结目录2022.10.19模拟赛小结更好的阅读体验戳此进入赛时思路T1CodeT2T3T4Code正解T1CodeT2T3T4CodeUPD(一场难度稍微低1丶丶的模拟赛,不过我太弱了,......
  • 2022.10.14 模拟赛小结
    2022.10.14模拟赛小结目录2022.10.14模拟赛小结题面PDF链接更好的阅读体验戳此进入赛时思路T1T2CodeT3CodeT4正解T1CodeT2CodeT3T4UPD大概是相对来讲补的比较全的一场......
  • Week - 2022/10/10~2022/10/16 周记
    Week-2022/10/10~2022/10/16周记Summary-2022/10/17Mon.11:56不要问我为什么又在下一周的周一才写上一周的总结。也不要为我为什么上周的总结这就结束了,懒。Day......
  • 2022年10月24日00:11:35
    越是年少的时候,越是懵懂的时期,越是勇敢,越是可以一往无前的追求自己想要的东西。越是经历的多,越是明白了越多道理,就越是胆小,畏缩,因为随着年纪的增长,要考虑的东西越来越多,要......
  • 2022陕西省赛
    链接:https://ac.nowcoder.com/acm/contest/44007B.Card前缀和#include"bits/stdc++.h"usingnamespacestd;usingi64=longlong;usingi128=__int128;voi......
  • 数组中的排序算法以及普通查找
    数组中的排序算法以及普通查找普通查找基本查找publicclassDemo01{publicstaticvoidmain(String[]args){int[]m={10,45,78,4,6,85,14,......
  • C4D2023取消永久许可?Maya推出精简版?你不能错过的7个CG软件资讯...
      忙碌了一个月,是不是没有时间看各类CG软件的最新资讯呀,云渲染小编特意整理了一下各大CG制作软件和渲染器的更新情况,方便大家了解行业最新动态!不知道是不是因为9月......