编程之美

来源:互联网 发布:新倩女幽魂辅助软件 编辑:程序博客网 时间:2024/06/06 00:56

问题导读:


在微软亚洲研究院上班,大家早上来的第一件事是干啥呢?查看邮件?No,是去水房拿饮料:酸奶,豆浆,绿茶、王老吉、咖啡、可口可乐……(当然,还是有很多同事把拿饮料当做第二件事)。


管理水房的阿姨们每天都会准备很多的饮料给大家,为了提高服务质量,她们会统计大家对每种饮料的满意度。一段时间后,阿姨们已经有了大批的数据。某天早上,当实习生小飞第一个冲进水房并一次拿了五瓶酸奶、四瓶王老吉、三瓶鲜橙多时,阿姨们逮住了他,要他帮忙。


从阿姨们统计的数据中,小飞可以知道大家对每一种饮料的满意度。阿姨们还告诉小飞,STC(Smart Tea Corp.)负责给研究院供应饮料,每天总量为V。STC很神奇,他们提供的每种饮料之单个容量都是2的方幂,比如王老吉,都是23=8升的,可乐都是25=32升的。当然STC的存货也是有限的,这会是每种饮料购买量的上限。统计数据中用饮料名字、容量、数量、满意度描述每一种饮料。


那么,小飞如何完成这个任务,求出保证最大满意度的购买量呢?


解决方案:


package Chapter1;import java.io.*;public class Func_1_6_1 {    public static void main(String []args) {        Func_1_6_1 f = new Func_1_6_1();        Beverage []beverages = f.getData("/data/BeautyProgramming/Func_1_6_1.txt");        System.out.println(f.digitSatisfy(beverages, 7));    }    /*    Opt(v`,i) 为从i到最后一种饮料中,算出总量为v`的最大满意度之和    Opt = max{        k*Hi + Opt(v` - vi*k, i+1)    }     */    // volume时最大满意度    int digitSatisfy(Beverage []beverages, int volume) {        // 如果beverages 没有数据,或者volume为0 直接返回 -1        if (beverages == null || beverages.length == 0 || volume == 0) {            return -1;        }        //创建opt数组        int v = volume;        int t = beverages.length;        int [][]opt = new int[v+1][t+1];        //初始化opt        int INF = 1000;        opt[0][t] = 0;        for (int i = 1; i <= v; i++) opt[i][t] = -INF; // 边界        for (int i = t-1; i >= 0; i--) {            int mark = beverages[i].mark;            int content = beverages[i].content;            int count = beverages[i].count;            // 体积            for (int j = 0; j <= v; j++) {                opt[j][i] = -INF; // 相对边界                // max                for (int k = 0; k <= count; k++) {                    if (j < k*content) break;                    int x = opt[j-k*content][i+1] + mark*k;                    if (x >= opt[j][i]) opt[j][i] = x;                }            }        }        /*        装不满:        3        1 4 2        2 4 3        3 4 4         */        int res = -INF;        for (int []i : opt)            res = i[0] > res ? i[0] : res;        return res; // 状态转移公式的最外层结果    }    // 饮料    class Beverage {        int mark; // 打分        int content; // 容量        int count; // 数量        public Beverage(int mark, int content, int count) {            this.mark = mark;            this.content = content;            this.count = count;        }    }    // 将string 转int    int[] parseInt(String []str) {        int []res = new int[str.length];        for (int i = 0; i < str.length; i++) {            res[i] = Integer.parseInt(str[i]);        }        return res;    }    // 得到data    Beverage[] getData(String file_path) {        Beverage []beverages;        BufferedReader reader = null;        try {            reader = new BufferedReader(                    new InputStreamReader(                            new FileInputStream(                                    new File(file_path))));            String line = null;            String []str;            int []digit;            int total = Integer.parseInt(reader.readLine());            beverages = new Beverage[total];            for (int i = 0; i < total; i++) {                if ((line = reader.readLine()) != null) {                    str = line.split(" ");                    digit = parseInt(str);                    int mark = digit[0];                    int content = digit[1];                    int count = digit[2];                    beverages[i] = new Beverage(mark, content, count);                }            }            return beverages;        } catch (Exception e) {            e.printStackTrace();            return null;        }    }}

92 1 23 1 25 1 34 1 36 2 25 2 34 2 418 4 112 4 2

33