WOJ1018-King Kong

本文介绍了一个有趣的算法问题——“金刚搬石”。问题描述了金刚需要将随机放置的石头按照特定顺序重新排列,以减少体力消耗。文章提供了一种有效的算法解决方案,并通过示例输入输出展示了算法的具体应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Have you seen the movie King Kong? If you have seen it, you must be impressed by the scene of the exciting fight between dinosaurs and
King Kong,right? Though the dinosaurs have been fight off, King Kong has been injured very heavily. Considering that dinosaurs will come back
very quickly, King Kong brings a lot of stones for fear that the dinosaurs attack again.

Now King Kong has arranged the stones at random in one line. But Different alignments of these stones would be different to King Kong. If the
alignment is not the target in his mind, he will move the stones to their proper positions. Taking the physical consumption into consideration,
King Kong could swap only two stones (whose weight is a and b weight units) at one time and for each time he will consume a+b thermal units.
In order to minimize the physical consumption, King Kong should set a plan to move these stones. But this is too complex for king Kong and
he needs your help.

输入格式

There are several test cases. For each test case, it contains:
Line 1: One integer N (1<=N<=5000) which specifies the total number of stones.
Line 2: N integers (you are ensured that the absolute value of each integer is less than) which the weight of each stone initially. These numbers
specify the initial stone alignment. There is a blank between two consecutive integers.
Line 3: N integers (you are ensured that the absolute value of each integer is less than ) which the weight of each stone finally. These numbers
specify the target alignment in King Kong?s mind. There is a blank between two consecutive integers.The input will be ended by zero.

输出格式

Output the answer of the minimum total thermal units consumed by King Kong in the stone moving process.

样例输入

3
3 2 1
1 2 3
3
1 2 3
1 2 3
4
8 1 2 4
1 2 4 8
0

样例输出

4
0
17

//首先找出序列中所有的置换,然后对于每个置换有两种方法将其调成合法。  
//1.每次用置换中最小的数去和其他数换,ans=sum+min*(num-2)。  
//2.用全局最小的元素换所有元素,最后还要把这个元素换出去,ans=sum+allmin*(num+1)。  
//对于每个置换两种方案取min值相加就可以了。  
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <math.h>  
#include<iostream>  
using namespace std;  
int h1[65537];//存储数所在的位置  
int h2[65537];//金刚想要数所在的位置  
int a[5001];  //第一行数  
int b[5001];  //第二行数  
bool sign[5001];//标记这个数是否移动到所想位置  
int main()  
{  
    //freopen("in.txt", "r", stdin);  
    int n, i, k, tp, cost, q,min;  
    while (scanf("%d", &n) != EOF && n != 0)  
    {  
        min = 65538;  
        memset(sign, 0, sizeof(sign));  
        cost = 0;  
        for (i = 1; i <= n; i++)  
        {  
            scanf("%d", &a[i]);  
            if (a[i] < min) min = a[i];  
            cost += a[i];//每个数都至少要交换一次  
            h1[a[i]] = i;  
        }  
        for (i = 1; i <= n; i++)  
        {  
            scanf("%d", &b[i]);  
            h2[b[i]] = i;  
        }  
        for (i = 1; i <= n; i++)  
            if (!sign[i])  
            {  
                tp = 65538;//记录循环中最小的数  
                q = i;  
                k = 0;//循环个数  
                do//找到循环个数和循环中最小的数  
                {  
                    sign[q] = true;  
                    if (b[q] < tp)  
                        tp = b[q];  
                    q = h1[b[q]];  
                    k++;  
                }while (q != i);  
                cost += (k - 2) * tp < tp + (k + 1) * min ? (k - 2) * tp : tp + (k + 1) * min;//两种方式中选择小的  
            }  
        printf("%d\n", cost);  
    }  
    return 0;  
}  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值