打破2组中1到n个数的排列[关闭]
Posted
技术标签:
【中文标题】打破2组中1到n个数的排列[关闭]【英文标题】:breaking permutation of 1 to n number in 2 set [closed] 【发布时间】:2020-04-27 20:18:44 【问题描述】:问题链接:https://codeforces.com/contest/1295/problem/E
这个问题表明存在 1 到 n 个数字的排列,这样每个数字只出现一次
例如。对于 n = 3,p = [ 1,2,3] 或 [2,1,3]。
现在对于 p 中的每个排列,排列 p 的第 ith 个元素都有一个成本 ci。每当我将 ith 元素从一组移到另一组时,我都必须支付 ci。
因此,问题要求我在任意位置 k 处打破两组排列,使得 1
例如
p = [3,1,2] c = [7,1,4]。
set1 = [3,1] & set2 = [2]。 所以现在我们可以以 4 的最低成本将 2 从 set2 发送到 set1。
更多示例请参考问题。链接在上面。
我的方法:
对于任何 k 我们需要在 set1 中有 1 到 k 个元素并在 set2 中休息。 所以让我们从
i = 1
开始,继续前进直到i = n-1
&& 在我维护pfx ans 的每个位置。 要计算每个pos = i
的pfx 数组,如果p[i] > i
,那么我们需要添加成本,因为我们必须将元素转移到set2
,如果它小于i
,那么我们需要减去因为我们想要之前,所以我们的总成本中有它。但现在我们不希望它成为我们的成本,因为我们拥有价值。同样,如果我有 cur 值,我也计算了每个位置。
这是我的代码。它通过了许多测试用例,但一直在第 10 位失败。无法理解原因。
请帮忙。
#include <bits/stdc++.h>
#define ll unsigned long long
#define pii pair<int,int>
using namespace std;
int main(void)
ll n , ans, prc3=0;
cin>>n;
vector<ll> p(n+1),a(n+1);
for(ll i=1; i<=n; i++) cin>>p[i];
for(ll i=1; i<=n; i++) cin>>a[p[i]], prc3 += a[p[i]];
ll prc1=0, prc2=0;
ll ans1=INT_MAX, ans2=INT_MAX, ans3=INT_MAX;
vector<bool> vst(n+1,false);
for(ll i=1; i<n; i++)
if(p[i]>i)
prc1 += a[p[i]];
else if(p[i]<i)
prc1 -= a[p[i]];
if(vst[i])
prc1 -= a[i];
vst[p[i]] = true;
if(!vst[i])
prc1 += a[i];
ans1 = min(ans1,prc1);
prc2 += a[p[i]];
ans2 = min(ans2,prc2);
prc3 -= a[p[i]];
ans3 = min(ans3,prc3);
ans = min(ans1,ans2);
ans = min(ans,ans3);
cout << ans << endl;
return 0;
【问题讨论】:
如果有的话,应该把第十个测试用例的输入添加到问题中。 顺便说一句,将#include <bits/stdc++.h>
与using namespace std;
结合起来要非常小心,这可能是许多神奇神秘错误的来源。
您在这里主要与专业开发人员打交道,而不是与竞争激烈的程序员打交道,因此如果您希望代码可读,则需要删除程序的前四行等癌症代码.
@user4581301 不,这永远不会导致问题,第 10 种情况有超过 18000 个元素,百日咳值为 1e9
通过将[]
运算符替换为at
方法或通过valgrind 运行第十个测试用例,查看是否有任何向量超出范围。
【参考方案1】:
我不确定您的代码到底想做什么,但是从我自己解决这个问题并最终阅读editorial 来看,在我看来,在约束范围内实现解决方案需要树数据结构。
据我了解,我们保留了一个变量k
,它代表左侧的最高数字。我们从 1 开始 k
,然后迭代到 n
。同时,我们保留一棵树,其中每个键i
指向从位置i
开始创建当前k
分区的成本。
当我们增加k
时,所有在起始列表中大于或等于k
位置的分区起始位置i
s 将不需要移动该元素,因此我们更新所有那些@ 987654331@s,使用树在O(log n)
时间内从每一个中减去A[p[k]]
;并更新所有指向小于k
的分区起始位置的i
s,将移动的成本添加到每个位置。我们在每次迭代中取最低成本。
据我所知,O(log n)
时间段的更新需要树形数据结构。
【讨论】:
以上是关于打破2组中1到n个数的排列[关闭]的主要内容,如果未能解决你的问题,请参考以下文章