Vijos P1133 装箱问题

来源:互联网 发布:网络电视经常卡怎么办 编辑:程序博客网 时间:2024/05/16 07:43

描述

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

格式

输入格式

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

输出格式

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

分析

和之前一样,我们从决策入手,首先我们的决策和01背包一样,是当前物品是否放入,决策的策略是加入这件物品是否能让我们箱内的空间变的最小?为了更加清晰的定义出我们的策略,我们定义状态,该问题中我们的要素应该有两个,一个是序列i,还有一个是物品的体积v,从结论入手我们不难发现,我们需要定义的状态也应该是v,但是如果我们仅仅把要素v当作状态本身的话,那么我们在决策第i个物品是否放入的话,除了箱子剩下的体积已经放不下第i个物品时,其他情况只能的到“放入“这个唯一得结果,这明显是错误的,出现这样错误的原因时决策,是因为没有考虑到v这个要素(把它当做参数),综上我们的状态应该是一个把i和v当作参数,v当作本质的状态,我们定义状态f[i][c]为前i个物品在空间为c时的最大体积,这样下来我们发现其实和01背包是完全一样的问题。
////  main.cpp//  装箱问题////  Created by 张嘉韬 on 16/1/10.//  Copyright © 2016年 张嘉韬. All rights reserved.//#include <iostream>#include <cstdio>using namespace std;int f[500][200100];int max(int a,int b){    if(a>b) return a;    else return b;}int main(int argc, const char * argv[]) {    //freopen("/Users/zhangjiatao/Desktop/input.txt","r",stdin);    int v,n,w[500];    cin>>v>>n;    for(int i=1;i<=n;i++)    {        cin>>w[i];    }    for(int j=1;j<=v;j++)    {        if(j<w[1]) f[1][j]=0;        else f[1][j]=w[1];    }    for(int i=1;i<=n;i++)    {        f[i][0]=0;    }    for(int i=2;i<=n;i++)    {        for(int j=1;j<=v;j++)        {            if(w[i]<=j)            {                f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+w[i]);            }            else            {                f[i][j]=f[i-1][j];            }        }    }    cout<<v-f[n][v];//    for(int i=1;i<=n;i++)//    {//        for(int j=1;j<=v;j++)//        {//            cout<<f[i][j]<<" ";//        }//        cout<<endl;//    }    return 0;}

0 0
原创粉丝点击