C++ 2集中1到n个数的破缺置换
问题链接: 这个问题表明存在1到n个数字的排列,使得每个数字只出现一次 例如,对于n=3,p=[1,2,3]或[2,1,3] 现在对于p中的每个置换,置换p的第i个元素都有一个代价ci。每当我将第I个元素从一个集合移动到另一个集合时,我必须支付ci 因此,问题要求我在任意位置k处将排列分成两组,这样1i,然后我们需要增加成本,因为我们必须将元素转移到C++ 2集中1到n个数的破缺置换,c++,algorithm,dynamic-programming,C++,Algorithm,Dynamic Programming,问题链接: 这个问题表明存在1到n个数字的排列,使得每个数字只出现一次 例如,对于n=3,p=[1,2,3]或[2,1,3] 现在对于p中的每个置换,置换p的第i个元素都有一个代价ci。每当我将第I个元素从一个集合移动到另一个集合时,我必须支付ci 因此,问题要求我在任意位置k处将排列分成两组,这样1i,然后我们需要增加成本,因为我们必须将元素转移到set2,如果它小于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;
}
#包括
#定义ll unsigned long long
#定义pii对
使用名称空间std;
内部主(空)
{
lln,ans,prc3=0;
cin>>n;
向量p(n+1),a(n+1);
对于(ll i=1;i>p[i];
对于(ll i=1;i>a[p[i]],prc3+=a[p[i]];
ll prc1=0,prc2=0;
ll ans1=INT_MAX,ans2=INT_MAX,ans3=INT_MAX;
向量vst(n+1,假);
对于(ll i=1;ii)
{
prc1+=a[p[i];
}
否则,如果(p[i]我不确定您的代码正试图做什么,但从我自己努力解决这个问题到最终阅读,在我看来,在约束范围内实现解决方案需要一个树数据结构
据我所知,我们保留了一个变量,k
,它表示左侧的最大数字。我们从1开始k
,然后迭代到n
。同时,我们保留了一个树,其中每个键,I
,都指向从位置I
开始创建当前k
分区的成本
当我们增加k
时,所有i
s,即分区起始位置大于或等于起始列表中k
的位置,将不需要移动该元素,因此我们更新所有这些i
s,从O(log n)中的每个位置减去A[p[k]
使用树计算时间;并更新所有指向小于k
的分区起始位置的i
s,将移动的成本添加到每个位置。我们在每次迭代中取最小成本
据我所知,对O(log n)
时间段的更新需要一个树型数据结构。我不确定您的代码到底想做什么,但从我自己努力解决这个问题到最后阅读,在我看来,在约束范围内实现解决方案需要一个树型数据结构
据我所知,我们保留了一个变量,k
,它表示左侧的最大数字。我们从1开始k
,然后迭代到n
。同时,我们保留了一个树,其中每个键,I
,都指向从位置I
开始创建当前k
分区的成本
当我们增加k
时,所有i
s,即分区起始位置大于或等于起始列表中k
的位置,将不需要移动该元素,因此我们更新所有这些i
s,从O(log n)中的每个位置减去A[p[k]
使用树计算时间;并更新所有指向小于k
的分区起始位置的i
s,将移动的成本添加到每个位置。我们在每次迭代中取最小成本
据我所知,O(logn)中某个段的更新
时间需要一个树型数据结构。如果你有,你应该将第十个测试用例的输入添加到问题中。顺便说一句,将#include
与using namespace std;
结合起来,这可能会导致许多神奇的神秘bug。你在这里主要是与专业开发人员打交道,而不是com有竞争力的程序员,所以如果你想让你的代码可读,你需要删除癌症代码,比如程序的前四行。@user4581301不,这不会导致问题,第十个案例有18000多个元素,其whooping值为1e9。通过替换[]
运算符使用at
方法,或者通过valgrind运行第十个测试用例。如果您有,您应该将第十个测试用例的输入添加到问题中。顺便说一句,将#include
与使用名称空间std;
结合使用,这可能会导致许多神奇的神秘bug。您主要是在处理g这里有专业的开发人员,而不是有竞争力的程序员,所以如果你想让你的代码可读,你需要删除癌症代码,比如程序的前四行。@user4581301不,这不会导致问题,第十种情况下有18000多个元素,whooping值为1E9,看看你是否有向量m通过将[]
操作符替换为at
方法,或者通过valgrind运行第十个测试用例,从而超出范围。