外卖满减, 美团笔试题

01背包问题

题意,每件商品只能买一次,至少需要买多少钱的东西才能满X元钱。

如果我们知道了背包的容量大小,也就是我们有一共多少钱,目标就变成了,我们尽可能的买最多的东西,也就是使得总的价值最大。

我们依次枚举我们钱的大小(背包大小),求出背包大小固定的情况下,最大价值。

f[i][j]表示前i个商品的情况下,背包大小为j时,能买商品的价格最大值。

典型01背包问题状态转移:

f[i][j]=f[i-1][j], 不选的第i件商品

f[i][j] = f[i-1][j-a[i]], j >= a[i] , 背包容量够的情况下选择第i件商品。

我们遍历所有状态,求出价格最大值大于X 中最小的价值,就是该问题的答案。

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(), x = sc.nextInt();
        int[] a = new int[n];
        int sum = 0;
        for(int i=0; i < n; i++) {
            a[i] = sc.nextInt();
            sum += a[i];
        }
        int[][] f = new int[n+1][sum+1];
        for(int i=1; i <= n; i++) {
            for(int j=1; j <= sum; j++) {
                if(i == 1) {
                    if(j >= a[i-1]) f[i][j] = a[i-1];
                    continue;
                }
                f[i][j] = f[i-1][j];
                if(j - a[i-1] >= 0) 
                    f[i][j] = Math.max(f[i][j], f[i-1][j - a[i-1]] + a[i-1]);
            }
        }
        //System.out.println(Arrays.deepToString(f));
        int res = sum;
        for(int i=1; i <= n; i++) {
            for(int j=1; j <= sum; j++) {
                if(f[i][j] >= x && f[i][j] < res)
                    res = f[i][j];
            }
        }
        System.out.println(res);
    }
}
posted @ 2020-06-24 10:48  li修远  阅读(271)  评论(0编辑  收藏  举报