华为牛客网在线笔试题之流量问题

题目描述

题目其实就是01背包问题,流量相当于背包容量,金币数相当于物品价值

解决思路

题目的输入有点坑,没给一行输多少个,所以输入是一行,我一开始用c++实在不好处理输入,就转用Java实现了,因为Java有split函数好处理字符串。具体思路是w[]装物品重量,v[]装物品价值,c表示背包容量,m[i][j]表示容量为j时物品个数为i时的最大价值,采用动态规划实现:

当第i件物品的重量w[i]大于背包容量时,那么就不能放入

m[i][j] = m[i-1][j] (w[i] > j)

当第i件物品的重量w[i]不大于背包容量时,那么可以选择放入和不放入,m[i][j]取两种情况的最大值

①m[i][j] = m[i-1][j] (不放入时)

②m[i][j] = m[i-1][j-w[i]]+v[i] (放入时)

所以m[i][j] = max(①,②);

如何记录哪些物品被取了呢?

m[n][c]表示物品为n时容量为c时最大价值,用x[n]表时第i件物品取用情况,初始为0,1表示装入背包了。从i=n开始到i=1来遍历,如果m[i][c] = m[i-1][c]说明第i件物品没被取用,因为价值都相同。如果不相等的话说明第i件物品被装入背包中,记x[i]=1,然后把容量c减去该物品的容量,继续遍历。最后判断第0件物品有没有取就看m[1][c]是否大于0,大于0就说明第0件物品被取了。

代码如下:

import java.util.Scanner;

public class Solution {
	public static void main(String[] args) {
		
    	Scanner input = new Scanner(System.in);
    	int c;//背包容量
    	c = Integer.parseInt(input.nextLine());
    	
    	String string = input.nextLine();//输入第一行为背包重量
    	String[] wS = string.split(" ");
    	int[] w = new int[wS.length+1];
    	int[] v = new int[wS.length+1];
    	for(int i = 0; i < wS.length; i++) {//把背包重量转入到w重量数组中,同时输入v价值数组
    		w[i+1] = Integer.parseInt(wS[i]);
    		v[i+1] = input.nextInt();
    	}
    	
    	int n = wS.length;
    	int[][] m = new int[c+1][c+1];//i件物品容量为j时的最大价值
    	
    	for(int i = 1; i <= n; i++) {//第i件物品
    		for(int j = 1; j <= c; j++) {//容量为j时
    			if(w[i] <= j) {//重量小于背包容量
    				m[i][j] = Math.max(m[i-1][j], m[i-1][j-w[i]]+v[i]);
    			}
    			else//重量大于背包容量
    				m[i][j] = m[i-1][j];
    		}
    	}
    	
    	
    	int[] x = new int[n+1];//存是否被放入
    	for(int i = n; i > 1; i--) {
    		if(m[i][c] == m[i-1][c])
    			x[i] = 0;//没被放入
    		else {
    			x[i] = 1;//被放入,容量减去该物品的重量
    			c -= w[i];
    		}
    	}
    	if(m[1][c] > 0)
    		x[1] = 1;
    	
    	//输入哪些物品被取用了
    	boolean isF = true;
    	for(int i = 1; i <= n; i++) {
    		if(isF && x[i] > 0) {
    			isF = false;
    			System.out.print(i);
    			continue;
    		}
    			
    		if(!isF && x[i] > 0)
    			System.out.print(" " + i);
    	}
    	
    }
}

 

华为牛客网在线笔试题之流量问题_第1张图片

 

 

你可能感兴趣的:(笔试面试)