• 有趣背包问题


    其实就是背包问题的一种应用,至于为什么起这么个名字,可以去问问神犇zhhx。。。

    问题描述和01背包几乎一样,你有m元钱,有n个物品可供选择,每个物品都有各自的花费c和价值v,而且每件物品只可以选择一次,问在花费不超过m元的条件下,最大价值是多少。

    嗯,就是和普通的01背包一样,不同之处在于数据范围,m,c<=10^9,n<=100,1<=v<=5。如果还和普通的背包一样,设dp[i][j]表示考虑完第i件物品,花费为j元的最大价值,显然是行不通的。

    我们发现花费取值范围太大,而价值取值范围较小,可以交换一下状态和最优值,设dp[i][j]表示考虑完第i件物品,价值为j元时的最小花费,那么满足dp[i][j]<=m的最大的j就是答案。

    然后就和普通的01背包没啥区别了,该滚动数组就滚动。

    附一道题,可以考虑用这种方法做,NOIP2005普及组 采药:https://www.luogu.org/problemnew/show/P1048

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 
     5 using namespace std;
     6 
     7 const int maxv = 1e4 + 5;
     8 
     9 int dp[maxv];
    10 
    11 int main() {
    12     int m, n, c, v, mv = 10000, ans = 0;
    13     scanf("%d%d", &m, &n);
    14     memset(dp, 0x3f3f3f3f, sizeof(dp));
    15     dp[0] = 0;
    16     for (int i = 1; i <= n; ++i) {
    17         scanf("%d%d", &c, &v);
    18         for (int j = mv; j >= v; --j) {
    19             dp[j] = min(dp[j], dp[j - v] + c);
    20             if (i == n && dp[j] <= m) ans = max(ans, j);
    21         }
    22     }
    23     printf("%d", ans);
    24     return 0;
    25 }
    AC代码
  • 相关阅读:
    Mysql 系列 | 事务隔离
    Mysql 系列 | 索引(优化器索引选择异常处理)
    Mysql 系列 | count(*)
    K8S入门篇资源调度
    K8S入门篇配置管理
    k8s入门篇资源管理
    k8s入门篇持久化存储管理
    操作crontab
    go Printf 语句的占位符 Format
    go中的 4种 for循环
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9896344.html
Copyright © 2020-2023  润新知