• [Offer收割]编程练习赛11 题目2 : 物品价值


    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    小Hi现在有n个物品,每个物品都有一个价值。并且这n个物品总共有m个不同的属性,每个物品都具有其中若干属性。

    小Ho要从中选出若干物品,满足每个属性都正好有奇数个物品拥有,且被选出的物品价值总和最大。你能帮助小Ho完成任务么?

    输入

    第一行一个数T(<=10),表示数据组数。对于每一组数据:

    第一行两个数n,m(1<=n<=1000,m<=10)

    接下来每两行描述一件物品。对于每一件物品:

    第一行两个数v和s,表示其价值和所含属性数量(v<=100000,s<=m)

    第二行s个数,表示该物品拥有的属性编号(1<=编号<=m)

    输出

    物品价值总和的最大值。

    样例输入
    1
    3 2
    2 1
    1
    2 1
    2
    5 2
    1 2
    
    样例输出
    5

    思路

    状态压缩DP。

    状态定义:

      dp[i][j]表示可选物品为[0, i]时,各属性奇偶状态为j的最大价值。

    状态转移:

      不选择第i个物品时,dp[i][j] = max(dp[i][j], dp[i - 1][j]);

      选择第i个物品时,dp[i][s1] = max(dp[i][s1], dp[i - 1][j] + v[i]),其中s1 = j ^ p[i],对应于添加物品i后发生的状态转移。

    代码

     1 import java.util.Arrays;
     2 import java.util.Scanner;
     3 
     4 public class Main {
     5 
     6     public static int resolve(int[] v, int[] p, int n, int m) {
     7         final int STATES = 1 << m;
     8         int[][] dp = new int[n + 1][STATES];
     9         for (int i = 0; i <= n; i++) {
    10             Arrays.fill(dp[i], -1);
    11         }
    12 
    13         dp[0][0] = 0;
    14         for (int i = 1; i <= n; i++) {
    15             for (int j = 0; j < STATES; j++) {
    16                 if (dp[i - 1][j] < 0)
    17                     continue;
    18                 dp[i][j] = Math.max(dp[i][j], dp[i - 1][j]);
    19                 int s1 = j ^ p[i - 1];
    20                 dp[i][s1] = Math.max(dp[i][s1], dp[i - 1][j] + v[i - 1]);
    21             }
    22         }
    23 
    24         return dp[n][STATES - 1];
    25     }
    26 
    27     public static void main(String[] args) {
    28         Scanner sc = new Scanner(System.in);
    29         int t = sc.nextInt();
    30         while (t-- > 0) {
    31             int n = sc.nextInt();
    32             int[] v = new int[n];
    33             int[] p = new int[n];
    34             int m = sc.nextInt();
    35             for (int i = 0; i < n; i++) {
    36                 v[i] = sc.nextInt();
    37                 int pcnt = sc.nextInt();
    38                 for (int j = 0; j < pcnt; j++) {
    39                     p[i] |= (1 << (sc.nextInt() - 1));
    40                 }
    41             }
    42 
    43             System.out.println(resolve(v, p, n, m));
    44         }
    45     }
    46 }
  • 相关阅读:
    web.xml配置详解(转载)
    http协议无状态中的 "状态" 到底指的是什么?!(转载)
    sublime配置python运行环境
    Eclipse下载安装教程
    局域网访问文件共享了访问不了解决方法
    ThreadLocal实现线程级上下文
    Spring中ApplicationEvent和ApplicationListener封装
    MySQL根据出生日期计算年龄的五种方法比较
    常用正则
    java.lang.OutOfMemoryError: PermGen space有效解决方法
  • 原文地址:https://www.cnblogs.com/deadend/p/6665626.html
Copyright © 2020-2023  润新知