快速过桥

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_44196094/article/details/102641878

快速过桥问题原题:

题意:有n个人要过桥,每次只能过一个或两个人,只有一个手电筒,所以如果还有人未过桥要有人把手电筒带回来,每个人过桥时间都不相同,问所有人过桥最少需要多长时间。

#include<stdio.h>

using namespace std;

const int N=1010;

int a[N];
int t;

void swap(int *a,int *b)
{
    int temp=*a;
    *a=*b;
    *b=temp;
}
void quick_sort(int l,int r)
{
    if(l>=r) return;
    int x=a[l+r>>1];
    int i=l-1,j=r+1;
    while(i<j)
    {
        do i++; while(a[i]<x);
        do j--; while(a[j]>x);
        if(i<j) swap(&a[i],&a[j]);
    }
    quick_sort(l,j);
    quick_sort(j+1,r);
}

int min(int a,int b)
{
    return (a<b?a:b);
}
int main(){
    //freopen("data.in","r",stdin);
    //freopen("data.out","w",stdout); 
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    quick_sort(1,n);
    int l=1,r=n;
    int res=0;
    while(1)
    {
        if(r-l+1==1)
        {
            res+=a[l];
            break;
        } 
        else if(r-l+1==2)
        {
            res+=a[r];
            break;
        }
        else if(r-l+1==3)
        {
            res+=a[l]+a[l+1]+a[l+2];
            break;
        }
        else
        {
            res+=min(a[l]+2*a[l+1]+a[r],2*a[l]+a[r-1]+a[r]);
            r-=2;
        }
    }
    printf("%d\n",res);
    return 0;
}

输入:
4
1
3
7
10
输出:
20

a事先排好序
思路就是:先枚举1<=n<=3三种情况:发现

n cost
1 a1
2 a2
3 a1+a2+a3

我们发现上表这样的规律。在枚举n==4的时候就比较sao,我们发现两种情况都有可能是最优解(a1 ,a2) (a1) (a3 a4) (a2)(a1 a2) 或(a1 a4) (a1) (a1 a3) (a1)(a1 a2) 那我们不妨选择其中最优解就可以了。

那如果遇上n>4怎么办?
我们设前两个数 L1,L2,后面两个数R1,R2
我们用n==4的规律,将n转化为n<=3 每次将R向前推进2,即可得到最优解.
通过比较 (a1 ,a2) (a1) (a3 a4) (a2) 和 (a1 a4) (a1) (a1 a3) (a1)我们用层层推进就可以的到最优解。

猜你喜欢

转载自blog.csdn.net/qq_44196094/article/details/102641878