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

    D14439. 【NOIP2001P】装箱问题

    时间限制1.0s   内存限制256.0MB   代码提交间隔1分钟(现在可以提交)  

    输入文件名:park.in   输出文件名:park.out

    试题来源:NOIP

    问题描述

      有一个箱子容量为V(正整数,0≤V≤20000),同时有n个物品(0≤n≤30,每个物品有一个体积(正整数)。

      要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。

    输入格式

      一个整数,表示箱子容量
      一个整数,表示有n个物品
      接下来n行,分别表示这n 个物品的各自体积

    输出格式

      一个整数,表示箱子剩余空间。

    样例输入

    24

    6

    8

    3

    12

    7

    9

    7

    样例输出

    0

     

    思路:

    定义f(v,n)为用n个物品填充V体积,该物品有选f(v-w[k],k-1)和不选f(v,k-1)两种情况,当n为零或是v<=0时为边界。

     

    f(V,N)=   Min(f(v-w[k],k-1),f(v,k-1))

            v (k=0)

            0 (v=0)

     

    Code:

    递归:

    #include<bits/stdc++.h>
    
     
    
    using namespace std;
    
     
    
    int v,n;
    
    int w[40];
    
    int dp[20010][40];
    
    int park(int vs,int k){
    
                   if (vs < 0) return vs + w[k+1];//科科因为最后一句没有比较当前容积和选中物品体积所以此处加判一句
    
                   if (vs == 0) return 0;
    
                   if (k == 0) return vs;
    
                   if (dp[vs][k]) return dp[vs][k];
    
                   return dp[vs][k] = min(park(vs - w[k],k - 1),park(vs,k - 1));
    
    }
    
     
    
    int main(){
    
                   freopen("park.in","r",stdin);
    
                   freopen("park.out","w",stdout);
    
                   cin >> v >> n;
    
                   for (int i = 1; i <= n; i++)
    
                                   cin >> w[i];
    
                   int ans = park(v,n);
    
                   cout << ans << endl;
    
                   return 0;
    
    }

    当然可以递推求解。

    Code:

    递推:

    #include<bits/stdc++.h>
    
     
    
    using namespace std;
    
     
    
    int v,n;
    
    int w[40],vs[20010];
    
     
    
    int main(){
    
                   freopen("park.in","r",stdin);
    
                   freopen("park.out","w",stdout);
    
                   cin >> v >> n;
    
                   for (int i = 1; i <= n; i++)
    
                                   cin >> w[i];
    
                   for (int i = 1; i <= n; i++){
    
                                   for (int j = v; j >= w[i]; j--)
    
                                                  vs[j] = max(vs[j],vs[ j-w[i] ] + w[i]);
    
                   }//递推过程,本质上是背包问题
    
                   int maxv = -1;
    
                   for (int i = 1; i <= v; i++)
    
                                   maxv = max(maxv,vs[i]);
    
                   cout << v - maxv << endl;
    
    }
  • 相关阅读:
    由二进制移位想到的
    KDJ指标详解
    PMP考试结束
    转K线理论初级二
    日本地震效应
    Baseline之流水先生的见解
    KDJ判断原则
    转K线理论初级一
    管理学法则
    今天提到KW,特此@Mark一下
  • 原文地址:https://www.cnblogs.com/sun915/p/9493656.html
Copyright © 2011-2022 走看看