• 「2015南阳CCPC D」金砖 解题报告


    金砖

    Problem

    有一个长度为L的板凳,可以放一排金砖,金砖不能重叠。特别的,摆放的金砖可以超出板凳,前提是必须保证该金砖不会掉下去,即该金砖的重心必须在板凳上。
    每块金砖都一个长度和价值,且金砖是规则的长方体。请计算最多可以摆放多少价值的金砖。

    Input Data

    第一行,两个整数N和L,分别表示金砖的数量和板凳的长度。
    接下来N行,每行两个整数,ai和vi,分别表示第i块金砖的长度和价值。

    Output Data

    一行,一个整数,表示最大价值。

    Input Sample 1

    3 7
    4 1
    2 1
    8 1
    

    Output Sample 1

    2
    

    Input Sample 2

    3 5
    4 1
    2 2
    8 9
    

    Output Sample 2

    11
    

    Input Sample 3

    1 1
    10 3
    

    Output Sample 3

    3
    

    思路

    要做这道题,得先掌握背包的一般思路,这里就不细讲了。

    先说下思路。

    At first,处理奇数长度的情况(没考虑清楚会WA一个点),因为对于奇数长度金砖,重心位置会出现小数的情况,这就让人很难堪。不过,可以把所有相关长度都乘2,或理解为以0.5为单位长度,这样就不用管奇数长度的情况了。

    Secondly,咋处理能长出板凳的情况???直接按题目思路不好考虑,就把它转换一下吧。首先,我们很容易得知,最边上的两块要最靠边,及刚好不掉下去,这样可以腾出更大的空间给放在中间的金砖s。然后呢?有些人可能会想预处理出所有不超过板凳长度能放多少价值,再枚举两边的金砖,最后取最大值。However,重复取金砖的情况怎么考虑???其实我们可以当做最靠边的金砖长度打五折,或者说有两个金砖长度折半,具体实现就是把f数组再开一维记录已经取了几个“半价“金砖,最后取最大值即可。

    Finally,还要考虑长度远大于L的金砖(更严谨地说,就是指长度 > 2 * L的金砖),它们即使“半价”处理也无法放上板凳,但是实际上可以把金砖的重心刚好放在板凳上,两边尽管长出去。好在这种情况会使金砖独占板凳,所以说直接用v来更新ans的值。

    具体实现就在下面啦:

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 4005
    #define LL long long
    
    int N, L;
    LL f[MAXN];
    
    int main(){
        scanf( "%d%d", &N, &L ); L *= 2;
        LL ans(0);//注意开long long !important
        for ( int i = 1; i <= N; ++i ){
            LL a, v;
            scanf( "%lld%lld", &a, &v );
            a *= 2;
            if ( a > L * 2 ) ans = max( ans, v );
            else
                for ( int j = L; j >= 1; --j ){//注意零一背包要倒过来
                    for ( int k = 0; k <= 2; ++k ){
                        if ( j >= a ) f[j][k] = max( f[j][k], f[j - a][k] + v );//放在中间
                        if ( k && j >= a / 2 ) f[j][k] = max( f[j][k], f[j - a / 2][k - 1] + v );//放在两边,既“半价处理”
                        ans = max( ans, f[j][k] );//更新ans的值
                    }
                }
        }
        printf( "%lld", ans );
        return 0;
    }
    

    撒花!(刚好下课)

  • 相关阅读:
    RESTful API
    访问方式由http改为https curl:(51)
    java.lang.OutOfMemoryError: PermGen space
    liunx下tomcat启动 Cannot find ./catalina.sh
    Java-编译后出现$1.class、$2.class等多个class文件
    错误处理的返回--异常还是返回值
    ubuntu 上安装温度检测
    mysql5.6不能输入中文
    jmap在ubuntu上DebuggerException: Can't attach to the process
    tomcat-reload-与内存泄露
  • 原文地址:https://www.cnblogs.com/louhancheng/p/10022952.html
Copyright © 2020-2023  润新知