• 【9906】装箱问题


    Time Limit: 10 second
    Memory Limit: 2 MB

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

    Input

    箱子的容量v 物品数n 接下来n行,分别表示这n个物品的体积

    Output

    箱子剩余空间


    Sample Input

    24
    6
    8
    3
    12
    7
    9
    7
    

    Sample Output

    0
    

    Sample Input1

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

    Sample Output1

    19
    

    【题解】

    这是将背包作为工具的问题。

    先用背包求出这些物品可以达到哪些容积值。

    这点可以用一个bool 型的can[]数组来得到。

    因为每个物品都只能拿一次,所以用0/1背包的更新方式,即倒序。

    for (j = maxv->w[i])

    if (can[j-w[i])

    can[j] = true;

    然后初值can[0] = true;其他can值都为false;

    最后从maxv逆序到一个最大的k,can[k]==true;

    然后输出maxv-k就可以了

    【代码】

    #include <cstdio>
    #include <cstring>
    
    int v,n,w[31];
    bool can[20010];
    
    void input_data()
    {
    	scanf("%d",&v);
    	scanf("%d",&n);
    	for (int i = 1;i <= n;i++) //输入这些物品的体积 
    		scanf("%d",&w[i]);	
    }
    
    void get_ans()
    {
    	memset(can,false,sizeof(can));
    	can[0] = true; //一开始什么都不放就可以达到0体积了 
    	for (int i = 1;i <= n;i++)
    		for (int j = v;j >= w[i];j--) // 按照0/1背包的更新方式就能得到其它可以达到的数值了 
    			if (can[j-w[i]])
    				can[j] = true;	
    	for (int i = v;i >= 0;i--) //然后逆序获得一个最大值。 
    		if (can[i])
    			{
    				printf("%d",v-i); //输出maxv减去这个值。就可以啦 
    				return;
    			}
    }
    
    int main()
    {
    	//freopen("F:\rush.txt","r",stdin);
    	input_data();
    	get_ans();
    	return 0;
    }
    


  • 相关阅读:
    JAVA 关键字
    github 上传代码到仓库

    创建链表及使用
    关于MAP文件的使用(转贴)
    styledcomponent使用(一)
    关于EDM模型中多个实体之间循环引用导致保存数据失败的解决方案一例
    C#格式化字符串
    [原]存取AVD设备SD卡中的文件
    NSStirng、NSArray、以及枚举(Method小集合)
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632385.html
Copyright © 2020-2023  润新知