• P1877 [HAOI2012]音量调节


    P1877 [HAOI2012]音量调节

    到达型01背包问题,开个bool的dp数组.

    此外还有滚动数组的用法.

     bool dp[i][j] 表示前i首歌能否到达j音量,则dp[0][beginLevel] = true.

    如果上一首歌音量能够达到j + s[i] 或 j - s[i], 那么当前歌曲就可以达到j,注意处理越界情况.

    尝试压维,变成dp[j],有如下代码:

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    int n, be, ma, s[60];
    bool dp[1010];
    
    int main(){
        cin >> n >> be >> ma;
        for(int i = 0; i < n; i++) cin >> s[i];
    
        dp[be] = true;
        for(int i = 0; i < n; i++)
            for(int j = ma; j >= 0; j--)
                if(j - s[i] >= 0)
                    if(j + s[i] <= ma) dp[j] = dp[j - s[i]] || dp[j + s[i]];
                    else dp[j] = dp[j - s[i]];
                else    // j - s[i] < 0
                    if(j + s[i] <= ma) dp[j] = dp[j + s[i]];
                    else dp[j] = false;
    
        
    
        return 0;
    }

    调试几下发现错得一塌糊涂.这里面的问题在于涉及到dp[j + s[i]],由于数组的覆盖问题,j + s[i]总是为已经更新的当前歌曲(从i更新到i + 1)的状态,这是个错误.

    为了避免这种干扰,来一招滚动数组轻松解决问题:

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    int n, be, ma, s[60];
    bool dp[2][1010];
    
    int main() {
        cin >> n >> be >> ma;
        for (int i = 0; i < n; i++) cin >> s[i];
    
        dp[0][be] = true;
        for (int i = 0; i < n; i++)
            for (int j = ma; j >= 0; j--)
                if (j - s[i] >= 0)
                    if (j + s[i] <= ma)
                        dp[(i + 1) & 1][j] = dp[i & 1][j - s[i]] || dp[i & 1][j + s[i]];
                    else
                        dp[(i + 1) & 1][j] = dp[i & 1][j - s[i]];
                else  // j - s[i] < 0
                    if (j + s[i] <= ma)
                    dp[(i + 1) & 1][j] = dp[i & 1][j + s[i]];
                else
                    dp[(i + 1) & 1][j] = false;
    
        for(int i = ma; i >= 0; i--)
            if(dp[n & 1][i]){
                cout << i << endl;
                return 0;
            }
        puts("-1");
    
        return 0;
    }

    这里 按位与 "&" 用以判断奇偶数.

    所以,虽然书上说开bool的dp经常会很浪费,但只要能够解决问题的时候不要思考受限,开它.

  • 相关阅读:
    js如何实现base64转文件下载保存到本地
    安装node及环境配置
    一定需要使用(N)Text吗?
    MS Sql Server EXECUTE
    [teach.net]表组织和索引组织
    Optimization Rules of Thumb[part of Technet Article]
    vs2008的用户自定义控件
    执行计划的缓存和重新使用
    保持索引的健康
    SQLServer性能优化计数器
  • 原文地址:https://www.cnblogs.com/Gaomez/p/14103150.html
Copyright © 2020-2023  润新知