zoukankan      html  css  js  c++  java
  • [Aizu] Knapsack Problem 背包问题

    问题

    传送门: Knapsack Problem

    描述

    你有N种物品想要放到一个背包里面去, 物品(i)有它的价值(v_{i})和重量(w_{i})
    你想要找到满足下面条件的物品:

    • 物品总价值尽可能的大
    • 所有物品的总重量不超过(W), 即背包的最大容量
    • 每一种物品你可以选取多次

    找到背包里物品的最大价值

    输入

    (N) (W)
    (v_{1}) (w_{1})
    (v_{2}) (w_{2})
    (.)
    (.)
    (v_{N}) (w_{N})

    第一行包含两个整数(N)(W), 接下来的每一行, 给出第(i)种物品的价值和重量

    输出

    在一行内输出最大价值

    样例输入1

    4 8
    4 2
    5 2
    2 1
    8 3
    

    样例输出1

    21
    

    样例输入2

    2 20
    5 9
    4 10
    

    样例输出2

    10
    

    样例输入3

    3 9
    2 1
    3 1
    5 2
    

    样例输出3

    27
    

    求解

    分析

    背包问题, 参见公式(来源: 维基百科 - 无界背包问题)

    dp[x]: 表示总重量不超过x的前提下, 总价值能到达的最大值
    显然, dp[x] 满足:
    dp[0] = 0
    dp[x] = max {dp[x - 1], {v[i] + dp[x - w[i]] | w[i] < x}}

    设计

    w[i]: 存储重量
    v[i]: 存储价值
    dp[i]: 总重量不超过i时的最大价值
    按照分析的公式, 使用动态规划的方法求解

    编码

    #include <bits/stdc++.h>
    using namespace std;
    #define MAX_N 105
    #define MAX_W 10005
    int main(void) {
    	int dp[MAX_W], v[MAX_N], w[MAX_N];
    	int N, W;
    	cin >> N >> W;
    	for (int i = 0; i < N; i++) {
    		cin >> v[i] >> w[i];
    	}
    	dp[0] = 0;
    	for (int j = 1; j <= W; j++) {
    		dp[j] = dp[j - 1];
    		for (int i = 0; i < N; i++) {
    			if (w[i] <= j) {
    				dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
    			}
    		}
    	}
    	cout << dp[W] << endl;
    }
    

    结果

    总结

    ...

  • 相关阅读:
    【书上讲解】平面上最近点对问题
    【书上讲解】快速排序
    【书上讲解】归并排序的非递归写法
    【例题 2-6】汉诺塔问题
    汉诺塔问题详解
    【例题2-5】整数的划分
    【例题2-4】排列问题
    【1-5】最大间隙问题
    【1-4】金币阵列问题
    【1-2】字典序问题
  • 原文地址:https://www.cnblogs.com/by-sknight/p/10940469.html
Copyright © 2011-2022 走看看