zoukankan      html  css  js  c++  java
  • hdu2126 类01背包(三维数组的二维空间优化)

    题目描述:

    对于给出的n个物品,每个物品有一个价格p[i],你有m元钱,求最多能买的物品个数,以及有多少种不同的方案

    题目分析:

    类似01背包的题目,一般的01背包问题我们遇到的是求n个物品,有m的容量,每个有w[i]的花费,求出容量范围内的价值的最大值,动态转移方程为dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + value[i]),dp[i][j]存放前i种物品,容量为j时价值的最大值,优化空间之后是dp[j] = max(dp[j], dp[j-w[i]] + value[i]),而用此题去类比01背包的题目的语境,此时把每次纪念品的价格都当做是1,我们需要求的是给定的容量m的最大价值的搭配方法

    原来就只需要求最大价值是多少,相当于多了一个维度存放搭配的数目,每一个i对应着一个二维数组,当更新当前第i个二维数组时,是根据第i-1个二维数组里的值更新的,所以此时需要用到三维数组存放,优化空间后可以用二维数组,且第2,3层循环都需要从大到小,避免干扰

    套用01背包对动态转移方程进行推导优化之前,dp[i][j][k]表示前i件物品,当有j元钱(不超过j元钱),可以购买k个物品的种数dp[i][j][k] = dp[i-1][j][k] + dp[i-1][j-p[i]][k-1],(前i个物品的有j元,买k个物品的种数为前i-1个物品j元买k个(第i个不买)或者i-1个物品j-p[i]元买k-1件物品的种数(第i个买)),优化空间后为dp[j][k] = dp[j][k] + dp[j-p[i]][k-1]

    需要注意的是初始化dp[i][0]都为1,意思是i元钱买0种物品的选择方案有1种就是不买

    代码:

     1 #include<iostream>
     2 #include<string.h>
     3 #include<algorithm>
     4 #include<cstdlib>
     5 #include<cmath>
     6 using namespace std;
     7 
     8 int p[35];
     9 int dp[505][35];
    10 
    11 int main(){
    12     int t;
    13     scanf("%d", &t);
    14     while(t--){
    15         int n, m;
    16         scanf("%d%d", &n, &m);
    17         for(int i = 1; i <= n; i++) scanf("%d", &p[i]);
    18         sort(p+1, p+n+1);
    19         int sum = 0;
    20         int ma = 0;
    21         for(int i = 1; i <= n; i++){
    22             if(sum + p[i] <= m){
    23                 sum += p[i];
    24                 ma = i;
    25             }
    26         }
    27         memset(dp, 0, sizeof(dp));
    28         for(int i = 0; i <= m; i++) dp[i][0] = 1;
    29         for(int i = 1; i <= n; i++){
    30             for(int j = m; j >= p[i]; j--){
    31                 for(int k = ma; k >= 1; k--){
    32                     dp[j][k] += dp[j-p[i]][k-1];
    33                 }
    34             }
    35         }
    36         if(ma != 0){
    37             printf("You have %d selection(s) to buy with %d kind(s) of souvenirs.
    ", dp[m][ma], ma);
    38         }else{
    39             printf("Sorry, you can't buy anything.
    ");
    40         }
    41     }
    42     return 0;
    43 }
  • 相关阅读:
    开源数据访问组件Smark.Data 1.8
    .NET应用加载容器KGlue
    TCP&UDP压力测试工具
    使用Beetle.Express简单构建高吞吐的TCP&UDP应用
    通过分析内存来优化.NET程序
    winsock I/O模型
    C++各大有名库的介绍
    深入研究 STL Deque 容器An InDepth Study of the STL Deque Container (By Nitron)
    C C++编程子资料库(小程序)
    VSS服务器安装配置(比较完整的一篇VSS服务器配置的文章)
  • 原文地址:https://www.cnblogs.com/YLTFY1998/p/11888388.html
Copyright © 2011-2022 走看看