我们有列表 A,在排序后需要看起来像列表 B,并且我们有每个数字的努力或“权重”,所以当我们按顺序交换时,努力也会交换,它们是连接的。
了解列表最后应该是什么样子找到将列表 A 排序为看起来像 lis B 所需的最低努力
我找到了对我的问题的回答,但它在 C++ 代码中位于底部
6 <--- how many numbers there is
w = [2400, 2000, 1200, 2400, 1600, 4000] <----- effort
a = [1, 4, 5, 3, 6, 2] <----- starting list
b = [5, 3, 2, 4, 6, 1] <----- how it should be sorted
所以当我们搬家的时候
2 和 5 我们取第二和第五重量并将它们相加,所以努力是 3600,列表看起来像这样
a = [1, 4, 2, 3, 6, 5]
sum_effort = 3600
然后我们在移动 3 和 4这个移动的努力又是 3600 和一个看起来像这样
a = [1, 3, 2, 4, 6, 5]
sum_effort = 7200
然后是 1 和 5,所以这个动作的努力是 4000,一个列表看起来像 b 列表
sum_effort 是 11200
我基于 C++ 所做的
weight = [2400, 2000, 1200, 2400, 1600, 4000]
og = [1, 4, 5, 3, 6, 2]
position = [5, 3, 2,4, 6, 1]
result = 0
for x in range(len(og)):
suma = 0
min_cycle = 0
len_cycle = 0
current = x
while(1):
min_cycle = min(min_cycle, weight[current])
suma = suma + weight[current]
current = position[current]
len_cycle += 1
if current == x:
break
result += min(suma+(len_cycle-2)*min_cycle, suma+min_cycle+(len_cycle+1)*min_weight)
print(result)
#include <cstdio>
#include <algorithm>
#define REP(a,n) for (int a=0; a<(n); ++a)
using namespace std;
#define INF 1000000000
typedef long long LL;
///////////////////////////
#define MAXN 1000000
int wagi[MAXN];
int orig[MAXN]; // orgin
int perm[MAXN]; // end_pos
bool vis[MAXN];
int minw = INF; // minimalna waga
int main()
{
int N;
scanf("%d", &N);
REP(a, N)
{
scanf("%d", &wagi[a]);
minw = min(minw, wagi[a]);
}
REP(a, N)
{
scanf("%d", &orig[a]);
--orig[a];
}
REP(a, N)
{
int nr;
scanf("%d", &nr);
--nr;
perm[nr] = orig[a];
}
LL wynik = 0;
REP(pocz, N)
if (!vis[pocz])
{
int minc = INF;
LL suma = 0;
int cur = pocz;
int dl = 0;
for (;;)
{
minc = min(minc, wagi[cur]);
suma += wagi[cur];
cur = perm[cur];
vis[cur] = true;
++dl;
if (cur==pocz)
break;
}
wynik += min(suma+(dl-2)*(LL)minc, suma+minc+(dl+1)*(LL)minw);
}
printf("%Ld\n", wynik);
}
我对python有点陌生,但如果我不明白这一点,我就不会睡觉