Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 竞争编码-以最低成本清除所有级别:不通过所有测试用例_Java_Arrays_Algorithm - Fatal编程技术网

Java 竞争编码-以最低成本清除所有级别:不通过所有测试用例

Java 竞争编码-以最低成本清除所有级别:不通过所有测试用例,java,arrays,algorithm,Java,Arrays,Algorithm,当我遇到这个问题时,我正在一个有竞争力的编码网站上解决问题。问题表明: 在这个游戏中有N个等级和M种类型的可用武器。等级编号从0到N-1,武器编号从0到M-1您可以按任何顺序清除这些级别。在每个级别中,需要这些M武器的某些子集来清除此级别。如果在特定关卡,你需要购买x件新武器,你将为此支付x^2硬币。还要注意的是,你可以携带你目前拥有的所有武器到下一个级别。最初,你没有武器。你能找出所需的最低硬币数,以便你能清除所有关卡吗 输入格式 输入的第一行包含2个空格分隔的整数: N=游戏中的关卡数 M=

当我遇到这个问题时,我正在一个有竞争力的编码网站上解决问题。问题表明:
在这个游戏中有N个等级和M种类型的可用武器。等级编号从0到N-1,武器编号从0到M-1您可以按任何顺序清除这些级别。在每个级别中,需要这些M武器的某些子集来清除此级别。如果在特定关卡,你需要购买x件新武器,你将为此支付x^2硬币。还要注意的是,你可以携带你目前拥有的所有武器到下一个级别。最初,你没有武器。你能找出所需的最低硬币数,以便你能清除所有关卡吗

输入格式 输入的第一行包含2个空格分隔的整数: N=游戏中的关卡数 M=武器类型的数量

下面是N行。这些行的第i行包含长度为M的二进制字符串。如果 这个字符串是1,这意味着我们需要一个j型武器来清除第i级

约束
1这个问题背后的逻辑是,每次你都必须找到对应于二进制字符串的最小设置位计数,该字符串将包含迄今为止在该级别中获得的武器

例如: 我们有如下数据: 4 3 101-2位 010-1位 110-2位 101-2位 现在,由于010有最小位,我们首先计算它的成本,然后更新当前模式(使用按位OR),所以当前模式是010 接下来,我们找到当前模式的下一个最小设置位wrt 我使用了这个逻辑,首先对当前模式和给定的数字使用异或,然后对当前数字(A^B)&A使用and 因此,在操作之后,位变成这样 (101^010)和101->101-2位 (110^010)&110->100-1位 现在我们知道最小位是110,我们选择它并计算成本,更新模式等等。。 此方法返回字符串相对于当前模式的成本

private static int computeCost(String currPattern, String costString) {
  int a = currPattern.isEmpty()?0:Integer.parseInt(currPattern, 2);
  int b = Integer.parseInt(costString, 2);
  int cost = 0;
  int c = (a ^ b) & b;
  cost = (int) Math.pow(countSetBits(c), 2);
  return cost;
    }

这个问题背后的逻辑是,每次你都必须找到一个二进制字符串对应的最小设置位计数,这个二进制字符串将包含迄今为止在该级别上获得的武器

例如: 我们有如下数据: 4 3 101-2位 010-1位 110-2位 101-2位 现在,由于010有最小位,我们首先计算它的成本,然后更新当前模式(使用按位OR),所以当前模式是010 接下来,我们找到当前模式的下一个最小设置位wrt 我使用了这个逻辑,首先对当前模式和给定的数字使用异或,然后对当前数字(A^B)&A使用and 因此,在操作之后,位变成这样 (101^010)和101->101-2位 (110^010)&110->100-1位 现在我们知道最小位是110,我们选择它并计算成本,更新模式等等。。 此方法返回字符串相对于当前模式的成本

private static int computeCost(String currPattern, String costString) {
  int a = currPattern.isEmpty()?0:Integer.parseInt(currPattern, 2);
  int b = Integer.parseInt(costString, 2);
  int cost = 0;
  int c = (a ^ b) & b;
  cost = (int) Math.pow(countSetBits(c), 2);
  return cost;
    }

这可以通过动态规划来解决

国家将是我们目前拥有的武器的小面具

过渡将是尝试从当前状态中依次清除每个
n
可能的级别,获取我们需要的额外武器并支付费用。 在每个
n
结果状态中,我们采用当前方法和所有以前观察到的方法的最小成本来实现它。 当我们已经拥有一些武器时,某些级别实际上不需要购买额外的武器;这样的转换将自动被忽略,因为在这种情况下,我们到达相同的状态,并支付相同的成本

我们从
m
0的状态开始,支付
0
。 最终状态是所有给定级别的按位OR,实现该状态的最低成本就是答案

在伪代码中:

let mask[1], mask[2], ..., mask[n] be the given bit masks of the n levels
p2m = 2 to the power of m
f[0] = 0
all f[1], f[2], ..., f[p2m-1] = infinity
for state = 0, 1, 2, ..., p2m-1:
    current_cost = f[state]
    current_ones = popcount(state)  // popcount is the number of 1 bits
    for level = 1, 2, ..., n:
        new_state = state | mask[level]  // the operation is bitwise OR
        new_cost = current_cost + square (popcount(new_state) - current_ones)
        f[new_state] = min (f[new_state], new_cost)
mask_total = mask[1] | mask[2] | ... | mask[n]
the answer is f[mask_total]

复杂度是
O(2^m*n)
时间和
O(2^m)
内存,这对
m应该是很好的,这可以通过动态规划来解决

国家将是我们目前拥有的武器的小面具

过渡将是尝试从当前状态中依次清除每个
n
可能的级别,获取我们需要的额外武器并支付费用。 在每个
n
结果状态中,我们采用当前方法和所有以前观察到的方法的最小成本来实现它。 当我们已经拥有一些武器时,某些级别实际上不需要购买额外的武器;这样的转换将自动被忽略,因为在这种情况下,我们到达相同的状态,并支付相同的成本

我们从
m
0的状态开始,支付
0
。 最终状态是所有给定级别的按位OR,实现该状态的最低成本就是答案

在伪代码中:

let mask[1], mask[2], ..., mask[n] be the given bit masks of the n levels
p2m = 2 to the power of m
f[0] = 0
all f[1], f[2], ..., f[p2m-1] = infinity
for state = 0, 1, 2, ..., p2m-1:
    current_cost = f[state]
    current_ones = popcount(state)  // popcount is the number of 1 bits
    for level = 1, 2, ..., n:
        new_state = state | mask[level]  // the operation is bitwise OR
        new_cost = current_cost + square (popcount(new_state) - current_ones)
        f[new_state] = min (f[new_state], new_cost)
mask_total = mask[1] | mask[2] | ... | mask[n]
the answer is f[mask_total]

复杂度是
O(2^m*n)
时间和
O(2^m)
内存,这对于
m应该很好@Gassa的动态优化思想可以通过估计剩余成本的最小值和最大值来扩展,其中

minRemaining(s)=bitCount(maxState-s)
maxRemaining(s)=bitCount(maxState-s)^2
从一个优先级队列开始—并以成本+最小剩余为基础—仅为空状态,然后将此队列中尚未达到maxState的状态替换为基于n个级别的最多n个新状态:

跟踪队列中的
bound=min(成本)+maxRemaining(剩余))
, 并使用
位计数(maxState)^2+1初始化所有成本

extract state with lowest cost
if state!=maxState
   remove state from queue
   for j in 1..n 
      if (state|level[j]!=state)
        cost(state|level[j])=min(cost(state|level[j]), 
           cost(state)+bitCount(state|level[j]-state)^2
        if cost(state|level[j])+minRemaining(state|level[j])<=bound
           add/replace state|level[j] in queue
else break

在最坏的情况下,操作的数量应该类似于动态优化,但在许多情况下会更好——我不知道最坏的情况是否会发生。

可以通过估计剩余成本的最小值和最大值来扩展@Gassa的动态优化思想,其中

minRemaining(s)=bitCount(maxState-s)
maxRemaining(s)=bitCount(maxState-s)^2
从一个优先级队列开始—并以成本+最小剩余为基础—仅为空状态,然后将此队列中尚未达到maxState的状态替换为基于n个级别的最多n个新状态:

跟踪队列中的
bound=min(成本)+maxRemaining(剩余))
, 并初始化al