贪心算法

1.过河问题:

一次只能乘坐两人,坐两个人的时候是他们之间的最大值。每个人都有一个渡河时间T,船划到对岸的时间等于船上渡河时间较长的人所用时间,现在已知N个人的渡河时间T,他们最少要花费多少时间,才能使所有人都过河。

思路:

n为1或2,直接过河

n为3,最长最短先过河,最短的回来接人

n为4,

策略一:

最长的人和最短的人先一起过去,然后用时最短的回来,再和第二长的人一起过去,最短的人回来。   t=2*time[0]+time[n-1]+time[n-2]

最短和第二短的人一起过去,然后最短的人回来,然后最长和第二长的人一起过去,第二短的人回来。t=2*time[1]+time[0]+time[n-1]

这两种都是把最长的两个人送过去了。

public static int crossRiver(int[] time,int n) {
        int t=0;
        if(n == 2)
        {
           return time[1];
        }
        else if(n == 3)
        {
           return time[0]+time[1]+time[2];
        }
        else{
            int t1 = 2*time[0]+time[n-1]+time[n-2];
            int t2 = 2*time[1]+time[0]+time[n-1]; //方案2  
            t = t1 > t2 ? t2 : t1;
        }
        return crossRiver(time, n - 2) + t;
    }
    public static void main(String[] args){ 
        Scanner in = new Scanner(System.in);
        int n=in.nextInt();
        for(int i=0;i<n;i++) {
            int len=in.nextInt();
            int[] T=new int[len]; 
            for(int j=0;j<len;j++) {
                T[j]=in.nextInt();
            }
            Arrays.sort(T);
            if (len==2)
            {
                System.out.print(T[1]);
            }
            else if (len==3)
            {
                System.out.print(T[0]+T[1]+T[2]);
            }
            else{
                System.out.print(Main.crossRiver(T, len));
            }
        }
    }

2.过河问题改进版本。

每次可以坐2或者3个人过去,每次必须至少有两个人。灰常麻烦(字节跳动笔试题),初始n一定大于等于2

和上面的类似,但比上面的麻烦多了,这里要利用第三第四小,所以要先把他们运过去。7个人的时候是一个中介点

public static int crossRiver(int[] time,int n) {
        int t=0;
        if(n<7) {
            int sum=3;
            for(int j=n;j>3;j--) {
                sum=sum+time[j-1]+2;
            }
            return sum;
        }
        else{
            //把后面3位移过去
            int t1=time[2]+time[1]+time[3]+time[1]+time[n-1]+time[3];//利用第3第4位
            int t2 =time[n-1]+time[2]+time[n-2]+time[2]+time[n-3]+time[2];//不利用
            t = t1 > t2 ? t2 : t1;
        }
        return crossRiver(time, n - 3) + t;
    }
    public static void main(String[] args){ 
        Scanner in = new Scanner(System.in);
        int n=in.nextInt();
        for(int i=0;i<n;i++) {
            int len=in.nextInt();
            int[] T=new int[len]; 
            for(int j=0;j<len;j++) {
                T[j]=in.nextInt();
            }
            Arrays.sort(T);
            if (len==2)
            {
                System.out.print(T[1]);
            }
            else if(len==3) {
                System.out.print(T[2]);
            }
            else if(len<7) {
                int sum=T[2];
                for(int j=len-1;j>2;j--) {
                    sum=sum+T[j]+T[1];
                }
                System.out.print(sum);
            }
            else
            {
                System.out.print(Main.crossRiver(T, len));
            }
        }
    }

 3.给定一部分区间,使得减去一部分区间(求减去的最小的区间)使得剩下的区间互相不重合

对end排序:

public int eraseOverlapIntervals(Interval[] intervals) {
        int len = intervals.length;
        if (len <= 1)return 0;
        Arrays.sort(intervals, (a,b) -> a.end - b.end);
        int count = 1;
        int end = intervals[0].end;
        for (int i = 1;i < intervals.length;i ++) {
            if (intervals[i].start < end) {
                continue;
            }
            count ++;//count就是不重合的区间的个数
            end = intervals[i].end;
        }
        return len - count;
    }

和上面的问题类似,也是区间分配问题(使得尽可能多的安排活动,也就是不能重叠的最大区间个数)

public ArrayList<Interval> eraseOverlapIntervals(Interval[] intervals) {
        int len = intervals.length;
        ArrayList<Interval> list=new ArrayList<>();
        if (len <= 1) return list;
        Arrays.sort(intervals, (a,b) -> a.end - b.end);
        int end = intervals[0].end;     
        list.add(intervals[0]);
        for (int i = 1;i < intervals.length;i ++) {
            if (intervals[i].start < end) {
                continue;
            }
            end = intervals[i].end;
            list.add(intervals[i]);
        }
        return list;
    }

 

posted @ 2019-04-14 13:58  LeeJuly  阅读(231)  评论(0)    收藏  举报