网易2017校招内推在线笔试编程题3

来源:互联网 发布:网络机顶盒刷机包下载 编辑:程序博客网 时间:2024/06/04 20:07

题目回忆
具体比较复杂,我按自己的理解(尚未知对否)简化为,将m x n数组,也就是田地,横竖各切三刀划分为16个分块,求如何切这6刀使得划分后的16块田地中最小价值的分块价值最大化,即最大化最小值问题。

解题思路
感觉应该是个动态规划问题,奈何不知如何解答(鄙人算法特别差),只能用暴力法解决,在这里也就是穷举法进行统计比对产生最优解。

import java.util.HashMap;import java.util.Iterator;import java.util.Map;public class Main {    public static void main(String[] args) {        //田地价值,记为m x n数组,这里为实验数据        int[][] land = {{3,3,4,4,4},                        {2,4,3,2,6},                        {4,4,5,3,3},                        {3,5,2,2,5},                        {3,5,2,2,5},                        {3,5,2,2,5},                        {3,5,2,2,5},                        {3,5,2,2,5}};        Main main = new Main();        main.distributeLandTo16(land);          }    /**     * 分成16块田地,横竖各切3刀     * @param arr     * @return     */    void distributeLandTo16(int[][] land) {        int m = land.length, n = land[0].length;        Map<String,Integer> allValues = new HashMap<String,Integer>(); //存放所有方案的各田地分块最小价值        // 这里分成16块田地,横竖各切3刀,记x1 x2 x3 y1 y2 y3        // 若第一横刀 x1 切 land[0] 和 land[1] 之间,则记 x1 值为0,以此类推,所以有范围如下:        // 0 <= x1 < x2 < x3 < m-1,0 <= y1 < y2 < y3 < n-1        int[] x = new int[5], y = new int[5];  //用数组存储,方便循环        x[0] = y[0] = -1;        x[4] = m-1;        y[4] = n-1;        //穷举暴力法        for (x[1] = 0; x[1] < m-3; x[1]++) {            for (x[2] = x[1]+1; x[2] < m-2; x[2]++) {                for (x[3] = x[2]+1; x[3] < m-1; x[3]++) {                    for (y[1] = 0; y[1] < n-3; y[1]++) {                        for (y[2] = y[1]+1; y[2] < n-2; y[2]++) {                            for (y[3] = y[2]+1; y[3] < n-1; y[3]++) {                                int[] values = new int[16];  //存放该种分田方法的16个分块的价值                                int cnt = 0;                                //计算每个田地分块的总价值,共16块                                for (int k = 0; k < 4; k ++) {                                    for (int l = 0; l < 4; l ++) {                                        //计算单个田地分块的价值                                        for (int p = x[k]+1; p <= x[k+1]; p++){                                            for (int q = y[l]+1; q <= y[l+1]; q++) {                                                values[cnt] += land[p][q];                                            }                                        }                                        cnt++;  //已计算完一个田地分块的价值                                    }                                }                                //存储具体分地方案,比如“012 134”代表x1=0, x1=1, x2=2, y1=1, y2=3, y3=4                                StringBuilder flag = new StringBuilder();                                for(int k = 1; k <= 3; k++) {                                    flag.append(x[k]);                                }                                flag.append(" ");                                for(int k = 1; k <= 3; k++) {                                    flag.append(y[k]);                                }                                allValues.put(flag.toString(), getMin(values));                            }                        }                    }                }            }        }        //求最小值最大化的方案,在最小值集合中求得最大值        Iterator it = allValues.keySet().iterator();        String maxKey = "";        int max = 0;        while (it.hasNext()) {            String str = (String) it.next();            if (max < allValues.get(str)) {                max = allValues.get(str);                maxKey = str;            }        }        System.out.println("最大化的最小值,即牛牛能得到的最大价值田地价值为:" + max);        System.out.println("分割方式为:" + maxKey);    }    /**     * 求arr数组中最小值     * @param arr     * @return     */    Integer getMin(int [] arr) {        int min = arr[0];        for (int num : arr) {            if (min > num)                min = num;        }        return min;    }}
0 0
原创粉丝点击