题解 | #购物单#

购物单

https://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main {

    static class Good {
        int v;
        int p;
        int q;
        int sub1;
        int sub2;

        public Good() {

        }

        public Good(int v, int p, int q) {
            this.v = v;
            this.p = p;
            this.q = q;
        }

        public int getV() {
            return v;
        }

        public void setV(int v) {
            this.v = v;
        }

        public int getP() {
            return p;
        }

        public void setP(int p) {
            this.p = p;
        }

        public int getQ() {
            return q;
        }

        public void setQ(int q) {
            this.q = q;
        }

        public int getSub1() {
            return sub1;
        }

        public void setSub1(int sub1) {
            this.sub1 = sub1;
        }

        public int getSub2() {
            return sub2;
        }

        public void setSub2(int sub2) {
            this.sub2 = sub2;
        }
    }

    public static int dw = 100;

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        boolean flag = true;
        // 获取第一行
        String line1 = br.readLine();
        // 第一行是N,钱的个数 m, 物品的个数
        String[] arr = line1.split(" ");
        int N = Integer.parseInt(arr[0]);
        int m = Integer.parseInt(arr[1]);

        Good[] A = new Good[m + 1];
        int i = 1;
        while (null != (line1 = br.readLine())) {
            arr = line1.split(" ");
            int v = Integer.parseInt(arr[0]);
            int p = Integer.parseInt(arr[1]);
            int q = Integer.parseInt(arr[2]);

            if (flag) {
                if (v % dw != 0) {
                    flag = false;
                    dw = 10;
                    for (int j = 1; j < i; j++) {
                        A[j].setV(A[j].v * 10);
                    }
                }
            }
            v = v / dw;
            // i可能在下面的q>0时已经进行了初始化
            if (null != A[i]) {
                A[i].setV(v);
                A[i].setP(p);
                A[i].setQ(q);
            } else {
                A[i] = new Good(v, p, q);
            }

            if (q > 0) {
                if (A[q] == null) {
                    A[q] = new Good();
                }
                // 优先填充附件一,再去填充附件二
                if (A[q].sub1 == 0) {
                    A[q].setSub1(i);
                } else {
                    A[q].setSub2(i);
                }
            }
            i++;
        }
        N = N / dw;
        dp(N, A);
    }

    public static void dp(int N, Good[] A) {
        int[][] dp = new int[N + 1][A.length];
        for (int i = 1; i < A.length; i++) {
            // v代表没有附件,v1代表有一个附件sub1.v2代表一个附件2,v3代表2个附件
            int v = -1, v1 = -1, v2 = -1, v3 = -1;
            int tempdp = -1, tempdp1 = -1, tempdp2 = -1, tempdp3 = -1;
            v = A[i].v;
            tempdp = v * A[i].p;

            // 拥有两个附件
            if (A[i].sub1 != 0 && A[i].sub2 != 0) {
                v3 = v + A[A[i].sub1].v + A[A[i].sub2].v;
                tempdp3 = tempdp + A[A[i].sub1].v * A[A[i].sub1].p + A[A[i].sub2].v *
                          A[A[i].sub2].p;
            }

            // 只拥有附件1
            if (A[i].sub1 != 0) {
                v1 = v + A[A[i].sub1].v;
                tempdp1 = tempdp + A[A[i].sub1].v * A[A[i].sub1].p;
            }

            // 只拥有附件2
            if (A[i].sub2 != 0) {
                v2 = v + A[A[i].sub2].v;
                tempdp2 = tempdp + A[A[i].sub2].v * A[A[i].sub2].p;
            }

            for (int j = 1; j < N + 1; j++) {
                // 并非主件
                if (A[i].q > 0) {
                    dp[j][i] = dp[j][i - 1];
                } else {
                    dp[j][i] = dp[j][i - 1];
                    if (j >= v && v != -1) {
                        dp[j][i] = Math.max(dp[j][i], dp[j - v][i - 1] + tempdp);
                    }
                    if (j >= v1 && v1 != -1) {
                        dp[j][i] = Math.max(dp[j][i], dp[j - v1][i - 1] + tempdp1);
                    }
                    if (j >= v2 && v2 != -1) {
                        dp[j][i] = Math.max(dp[j][i], dp[j - v2][i - 1] + tempdp2);
                    }
                    if (j >= v3 && v3 != -1) {
                        dp[j][i] = Math.max(dp[j][i], dp[j - v3][i - 1] + tempdp3);
                    }
                }
            }
        }
        System.out.println(dp[N][A.length - 1] * dw);

    }
}

全部评论

相关推荐

10-30 10:16
南京大学 Java
龚至诚:给南大✌️跪了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务