题目描述

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

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

分析

思路1:判定性dp

设表示用了前n个物品,能否达到容量j。

然后对取最大的就可以了。

思路2:偏离搜索

我们有种很好的思想:贪心。

先排序,然后每次尽可能取最大的。

但是这样是错误的。

我们考虑调整。

我们坚定几乎都是取最大的。

所以使用偏离搜索:只有限定次数能不取最大的。

结合一个剪枝:若之后的sum+当前的s<=v,则直接取完。

#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;

#define rep(i,a,b) for (int i=(a);i<=(b);i++)

const int N=32;
const int D=5;

int v,n;
int a[N];

int sum[N];
int res;

inline int rd(void)
{
    int x=0,f=1; char c=getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    for (;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}

void DFS(int w,int del,int s)
{
    if (s+sum[w]<=v)
    {
        res=max(res,s+sum[w]);
        return;
    }
    if (s+a[w]<=v)
    {
        DFS(w-1,del,s+a[w]);
        if (del<D) DFS(w-1,del+1,s);
    }
    else DFS(w-1,del,s);
}

int main(void)
{
    freopen("codevs1014.in","r",stdin);
    freopen("codevs1014.out","w",stdout);

    v=rd(),n=rd();
    rep(i,1,n) a[i]=rd();
    sort(a+1,a+n+1);

    rep(i,1,n)
        sum[i]=sum[i-1]+a[i];
    DFS(n,0,0);
    printf("%d\n",v-res);

    return 0;
}

思路3:随机化

我们有种很好的思想:贪心。

先排序,然后每次尽可能取最大的。

但是这样是错误的。

我们考虑不排序了。

多次随机序列,然后能取就取。

随机1000000次即可。

#include <cstdio>
#include <cctype>
#include <climits>
#include <algorithm>
using namespace std;

#define rep(i,a,b) for (int i=(a);i<=(b);i++)
#define per(i,a,b) for (int i=(a);i>=(b);i--)

const int N=32;
const int T=1000000;
const int MAX=INT_MAX;

int v,n;
int a[N];

int res;

inline int rd(void)
{
    int x=0,f=1; char c=getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    for (;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}

int Calc(void)
{
    int nv=0;
    rep(i,1,n)
        if (nv+a[i]<=v)
            nv+=a[i];
    return v-nv;
}

int main(void)
{
//  freopen("codevs1014.in","r",stdin);
//  freopen("codevs1014.out","w",stdout);

    v=rd(),n=rd();
    rep(i,1,n) a[i]=rd();

    res=MAX;
    rep(tms,1,T)
    {
        random_shuffle(a+1,a+n+1);
        int t=Calc(); res=min(res,t);
    }
    printf("%d\n",res);

    return 0;
}

小结

(1)伪判定性问题

我们称“是不是”这种问题为判定性问题。

而很多最值问题都可以通过判定性问题来表述,所以称这类问题为伪判定性的。

总之:许多判定性问题可以转化为最值问题

(2)骗分的思路

骗分要有思路才行。

常规的骗分被称为“老实的骗分”,常见dfs求解,再结合两个常见的剪枝:①ans>=sum ②now+rest<=v

但是,有时候我们假如能想到一些错误的贪心,那么就可以诞生一些很棒的方法。常见方法1:偏离搜索。常见方法2:随机排列顺序,这种方法可用于最大团的求解。

总之,要活学活用,具体题目还是要具体分析。

【CodeVS 1014】装箱问题的更多相关文章

  1. Codevs 1014 装箱问题

    题目描述 Description 有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有一个体积(正整数). 要求n个物品中,任取若 ...

  2. codevs 1014 装箱问题 2001年NOIP全国联赛普及组

    题目描述 Description 有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有一个体积(正整数). 要求n个物品中,任取若 ...

  3. 【动态规划】【零一背包】CODEVS 1014 装箱问题 2001年NOIP全国联赛普及组

    #include<cstdio> #include<algorithm> using namespace std; ],f[]; int main() { scanf(&quo ...

  4. wikioi 1014 装箱问题

    来源:http://wikioi.com/problem/1014/ 1014 装箱问题 29人推荐 收藏 发题解 提交代码 报错 题目描写叙述 输入描写叙述 输出描写叙述 例子输入 例子输出 提示 ...

  5. 1014 装箱问题 CODE[VS]

    1014 装箱问题 2001年NOIP全国联赛普及组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Descripti ...

  6. codevs 3152 装箱问题3

    装箱问题3 http://codevs.cn/problem/3152/ 题目描述 Description 设有n种物品,记作A1.A2.….An,对应于每个Ai(1<=i<=n)都有一个 ...

  7. 【wikioi】1014 装箱问题

    题目链接 算法:动态规划(01背包) 01背包思想:依次对待某一物体,考虑是否放入容量为V的背包中 用f[V]来表示容量为V的背包的最大价值,则决策是 f[V] = max{f[V], f[V-v[i ...

  8. codevs 1464 装箱问题 2

    题目描述 Description 一个工厂制造的产品形状都是长方体,它们的高度都是h,长和宽都相等,一共有六个型号,他们的长宽分别为1*1, 2*2, 3*3, 4*4, 5*5, 6*6.这些产品通 ...

  9. wikioi 1014 装箱问题(背包)

    题目描述 Description 有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有一个体积(正整数). 要求n个物品中,任取若 ...

随机推荐

  1. 【leetcode❤python】 112. Path Sum

    #-*- coding: UTF-8 -*-# Definition for a binary tree node.# class TreeNode(object):#     def __init_ ...

  2. SQLServer: 解决“错误15023:当前数据库中已存在用户或角色

    解决SQL Server 2008 错误15023:当前数据库中已存在用户或角色,SQLServer2008,错误15023, 在使用SQL Server 2008时,我们经常会遇到一个情况:需要把一 ...

  3. PHP工作原理

    文章一 :http://blog.csdn.net/21aspnet/article/details/6973405 简介 先看看下面这个过程: 我们从未手动开启过PHP的相关进程,它是随着Apach ...

  4. 图解SQL 2008数据库复制

    为了达到数据及时备份,一般采用完整备份+差异备份即可,或者再加上日志备份,本文介绍使用数据库复制技术同步数据: PS:文章以图片为主,图片更能直观的看出操作步骤和配置方法! 1.首先创建一个测试的数据 ...

  5. CUBRID学习笔记 31 通过select创建表

    语法 CREATE {TABLE | CLASS} <table_name> [( <column_definition> [,<table_constraint> ...

  6. Codeforces Round #288 (Div. 2) C. Anya and Ghosts 模拟

    C. Anya and Ghosts time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  7. POJ3009 Curling

    题目链接:http://poj.org/problem?id=3009 题意:从2出发,要到达3, 0可以通过,碰到1要停止,并且1处要变成0, 并且从起点开始沿着一个方向要一直前进,直至碰到1(或者 ...

  8. 图-用DFS求连通块- UVa 1103和用BFS求最短路-UVa816。

    这道题目甚长, 代码也是甚长, 但是思路却不是太难.然而有好多代码实现的细节, 确是十分的巧妙. 对代码阅读能力, 代码理解能力, 代码实现能力, 代码实现技巧, DFS方法都大有裨益, 敬请有兴趣者 ...

  9. .htaccess文件 301重定向URL重写[NC][R][F][L]是什么意思

    .htaccess中的[NC][R][F][L]几个标记是什么意思 NC: no case,就是说不区分大小写 R:redirect,重定向 F:forbidden,禁止访问 L:last,表示已经是 ...

  10. js 定时器的使用。 setInterval()

    我需要实现的功能是:点击发送按钮,会出现 “已发送60s后可点击重发”,并且,60s 这个数字是随时变化的,60,59,58,57....0,然后再次返回到 发送 按钮. 类似效果,可参考  360首 ...