Gym 101623I

来源:互联网 发布:大庆58同城网络交易 编辑:程序博客网 时间:2024/06/07 18:57

题意

app有两种大小,一个是下载安装包的大小d,一个是安装完之后变成大小s,这种app安装包很智能,安装的过程中是从安装包直接转化成了应用,整个过程不需要额外空间,只要手机有max(d,s)大小的空间就能装上去。现在为了尽可能安装多的app,要决定安装次序。

核心问题

找出贪心的顺序用01背包来dp

java代码

import java.util.Scanner;import java.util.Stack;import java.util.Vector;public class Main {    static class app implements Comparable<app> {        public int d, s, id;        public app(int d, int s, int id) {            super();            this.d = d;            this.s = s;            this.id = id;        }        @Override        public int compareTo(app o) {//比较函数,比较的是安装先后次序            int a = s + Math.max(o.d, o.s);//先装a,然后装b,安装过程中所需空间的最大值            int b = o.s + Math.max(d, s);//ͬ同理是先安装b,然后安装a,肯定是要让安装空间峰值尽可能小            if (a < b)                return -1;            if (a > b)                return 1;            return 0;        }//      public int compareTo(app o) {//这种贪心是错的//          if(s<o.s) return -1;//          if(s>o.s) return 1;//          if(d>o.d) return -1;//          if(d<o.d) return 1;//          return 0;//      }        @Override        public String toString() {            return "app [d=" + d + ", s=" + s + ", id=" + id + "]";        }        public int maxsize() {            return Math.max(d, s);        }    }    public static void main(String[] args) {        Scanner cin = new Scanner(System.in);        Integer n, c;        n = cin.nextInt();        c = cin.nextInt();        Vector<app> a = new Vector<>();        a.setSize(n);        for (int i = 0; i < n; i++) {            int d, s;            d = cin.nextInt();            s = cin.nextInt();            a.set(i, new app(d, s, i + 1));        }        a.sort(null);        int dp[][] = new int[n + 1][c + 1];//dp定义的是从前i个物品中选出总重量不超过j物品时候总价值最大值        for (int i = 0; i <= c; i++)            dp[0][c] = 0;        for (int i = 1; i <= n; i++) {            app u = a.elementAt(i - 1);            for (int j = 0; j <= c; j++) {                dp[i][j] = dp[i - 1][j];                if (j - u.s < 0)                    continue;                if (c - (j - u.s) < u.maxsize())//剩余空间能否满足条件                    continue;                dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - u.s] + 1);            }        }        int size=c;//不一定能装满        for(int i=0;i<=c;i++)            if(dp[n][i]>dp[n][size]) size=i;        Stack<Integer> stk = new Stack<>();        for (int i = n; i >= 1; i--) {//寻找路径            app u = a.elementAt(i - 1);            if (size - u.s < 0)                continue;            if (dp[i - 1][size - u.s] == dp[i][size] - 1) {                size = size - u.s;                stk.push(u.id);            }        }        System.out.println(stk.size());        while (stk.isEmpty() == false) {            int id = stk.pop();            System.out.print(id);            if (stk.isEmpty())                System.out.print('\n');            else                System.out.print(' ');        }        cin.close();    }}
原创粉丝点击