HDU5696(分治)

来源:互联网 发布:苹果手机 解压软件 编辑:程序博客网 时间:2024/06/05 18:00

我是看了这位大神写的http://m.blog.csdn.net/article/details?id=51477402

但是他没有做详细的解释,我来以我的理解解释一下。

首先对于区间(1,n)我们找到最小值min和最大值max,则ans[n]=min*max。

记录下min的位置minw,开始递归(1,minw-1)和(minw+1,n)

我称之为左右区间,区间大小为L和R,接下来是重点。

对于区间大小为  max(L,R)  至  n-1  的区间来说,他们必须包含区间(1,n)的最小值

而且他们能包含到区间(1,n)的最大值,所有他们的价值为(1,n)的价值。

对于区间大小为  L 至  R  的区间来说他们可以包含(1,n)的最小值也可以不包含。

选择不包含最小值的区间递归会把他的答案更新,选择包含的区间递归可能更新不到。

比如以下数据  8 22 54 7 89 45  , 7 89 45 的价值比 8 22 54 要大,但是递归为 8 22 54 和 89 45

 更新不到 7 89 45 但是对于ans[4]一定可以包含 7和89,

以上就是为了解释代码 

ans[i]=max(ans[i],ans[i+1]);

是如何工作的。

下面贴上java代码:


import java.util.Scanner;/* * 15 * 2 3 5 7 8 22 54 7 89 45 2 1 5 6 9 */public class Code { public static long ans[]=new long[100005]; public static long arr[]=new long[100005]; public static int n;      public static void main(String args[]){      Scanner in=new Scanner(System.in);            while(true){            try {n=in.nextInt();for(int i=1;i<=n;i++){      arr[i]=in.nextLong();} } catch (Exception e) {break; }                        for(int i=1;i<=100000;i++)      ans[i]=0;            f(1,n);            for(int i=n-1;i>=1;i--){      /*if(ans[i]==0)      ans[i]=ans[i+1];*/      //ans[i]=Math.max(ans[i],ans[i+1]);      }            for(int i=1;i<=n;i++);      //System.out.println(ans[i]);       }         }          public static void f(int l,int r){            if(!(r>=l&&1<=l&&r<=n)) return;            for(int i=l;i<=r;i++)      System.out.print(arr[i]+" ");      System.out.println();            if(l==r&&arr[l]*arr[r]>ans[1]) {      ans[1]=arr[l]*arr[r];      return;      }            long min=Integer.MAX_VALUE;      long max=Integer.MIN_VALUE;      int minw=0;            for(int i=l;i<=r;i++){      if(arr[i]>max) max=arr[i];      if(arr[i]<min){      min=arr[i];      minw=i;      }      }            if(min*max>ans[r-l+1]) ans[r-l+1]=max*min;            f(l,minw-1);      f(minw+1,r);     }}

原创粉丝点击