• 【题解】HNOI2004敲砖块


    题目传送门:洛谷1437

    决定要养成随手记录做过的题目的好习惯呀~

    这道题目乍看起来和数字三角形有一点像,但是仔细分析就会发现,因为选定一个数所需要的条件和另一个数所需要的条件会有重复的部分,所以状态不好转移,也会产生后效性。

    但是,通过将所有的砖块左移,我们可以发现(i, j)砖块所需要的条件就是(i-1, j) (i-1, j+1)这两块砖均被敲掉。

    所以dp方程顺理成章:i,j,k分别表示从第i列j行开始算起,取k个数所能获得的最大价值和。

    dp[i][j][s] = max(dp[i+1][s][k-j] +sum[第i列前j个数之和])(s>=j+1,<=该行最大数目)

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn 55
    #define maxm 1500
    int n, m, ans, sum[maxn][maxn], dp[maxn][maxn][maxm];
    int read()
    {
        int x = 0;
        char c;
        c = getchar();
        while(c < '0' || c > '9') c = getchar();
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x;
    }
    
    int main()
    {
        n = read(), m = read();
        for(int i = 1; i <= n; i ++)
            for(int j = 1; j <= n - i + 1; j ++)
                sum[j][i] += read() + sum[j][i - 1];
        for(int i = n; i >= 1; i --)
        {
            int len = n - i + 1;
            for(int j = 0; j <= len; j ++)
                for(int s = m; s >= max(0, 2 * j - 1); s --)
                    for(int k = j - 1; k <= len - 1; k ++)
                    {
                        dp[i][j][s] = max(dp[i + 1][k][s - j] + sum[i][j], dp[i][j][s]);
                        ans = max(ans, dp[i][j][s]);
                    }
        }
        printf("%d
    ", ans);
        return 0;
    }
  • 相关阅读:
    System.setProperty()
    ExtJs自学教程(1):一切从API開始
    【福利!】英雄联盟国服更新补丁速度极慢的解决方法
    ORACLE触发器具体解释
    我的Hook学习笔记
    Runood-JSP:JSP 客户端请求
    Runoob-JSP:JSP 隐式对象
    Runoob-JSP:JSP 动做元素
    Runoob-JSP:JSP 指令
    Runoob-JSP:JSP 生命周期
  • 原文地址:https://www.cnblogs.com/twilight-sx/p/8407172.html
Copyright © 2020-2023  润新知