zoukankan      html  css  js  c++  java
  • (转)装箱问题

    Description

    有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<=n<=30),每个物品有一个体积(正整数)。
    要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。

    Input

    每个测试文件只包含一组测试数据,每组输入的第一行为一个整数V(0<=V<=20000),表示箱子的容量。
    第二行输入一个整数n(0<=n<=30),表示有n个物品。
    接下来n行,每行输入一个正整数,表示每个物品的体积。

    Output

    对于每组输入数据,输出一个整数,表示箱子剩余的最小空间。

    Sample Input 1

    24
    6
    8
    3
    12
    7
    9
    7

    Sample Output 1

    0

    Sample Input 2

    90
    12
    3
    7
    4
    5
    13
    2
    8
    4
    7
    6
    5
    7
    Sample Output 2

    19

    解题思路:利用动态规划

    我自己一开始的错误思想是用贪心算法,觉得先把最大的存进去,剩余的体积就是最小。题目提供的样例都过了,但是提交的时候却在某个样例错了。后来想了想才知道我这种想法有错误之处,先贴出我自己的错误代码

     1 #include<iostream>
     2 #include<algorithm>
     3 using namespace std;
     4 
     5 int V,n;
     6 int a[40];
     7 int sum = 0;
     8 int main()
     9 {
    10     cin>>V;
    11     cin>>n;
    12     for(int i = 0 ;i < n ;i++)
    13     {
    14         cin>>a[i];
    15         sum += a[i];
    16     }
    17     if(sum<=V) cout<<V-sum;
    18     else 
    19     if(sum>V)
    20     {
    21         sort(a,a+n);
    22         for(int i = n-1 ;i>=0;i--)
    23         {
    24             V -= a[i];
    25             if(V<0)
    26             {
    27                 V += a[i];
    28                 continue;
    29             }
    30         }
    31         cout<<V;
    32      } 
    33      return 0;
    34      
    35 }

    但是这种的话,后来想了一下,对于该数据正确答案是输出0,但是上述代码输出了1;因为代码先把99存进去了;

    100
    4
    99 98 2 2

    后来看了别人的博客,是利用动态规划

    思路:

    对于每一个物体,都有两种选择-放入或者不放入,所以外层循环可对每个物品进行遍历,而每选择一个物品,定会对大于该物品体积的dp数组元素产生影响,从而还需要一个内层数组对大于该物品体积的dp数组元素进行遍历更新。更新方法为:dp[i] = max{ dp[i] , dp[i - vi]+vi },其中vi为当前物品的体积,max中的dp[i]表示不放入该物体时的解, dp[i - vi]+vi表示放入该物体时的解(i-vi表示给即将放入的物品留出合适的体积,如之前的例子,dp[i-vi]并不一定等于dp[i] - vi),取最大值,即为最优解。需要注意的是,需要先将dp数组中的每一个元素初始化为0。
    对于如何运用 dp[i] = max{ dp[i] , dp[i - vi]+vi },下面举个例子详细说明一下过程。
    原文:https://blog.csdn.net/elma_tww/article/details/86507716

     

    继续进行下去,直到遍历完所有物品。

    主要是思想,代码其实挺简单的,代码如下:

     1 #include<iostream>
     2 #include<cmath>
     3 #include<string.h>
     4 using namespace std;
     5 
     6 
     7 int V,n;
     8 int a[40];
     9 int main()
    10 {
    11     cin>>V;
    12     cin>>n;
    13     int dp[V+1];
    14     memset(dp,0,sizeof(dp)); 
    15     for(int i = 0 ;i < n;i++)
    16     {
    17         cin>>a[i];
    18         for(int j = V;j >= a[i];j--)
    19         {
    20             dp[j] = max(dp[j],dp[j-a[i]]+a[i]);
    21         }
    22     }
    23     cout<<V-dp[V];
    24     return 0;
    25 }
  • 相关阅读:
    C++ std::stack 基本用法
    linux6 安装 ntopng
    linux 6安装 redis2.6
    Linux6搭建Tomcat服务器
    EXSI6.5忘记root密码
    python3笔记--数字
    python3笔记--运算符
    python3基本数据类型
    python3笔记
    centos6.X升级python3.X方法
  • 原文地址:https://www.cnblogs.com/yewanting/p/10539576.html
Copyright © 2011-2022 走看看