zoukankan      html  css  js  c++  java
  • P1437 [HNOI2004]敲砖块 [dp]

    敲砖块

    在一个凹槽中放置了 n 层砖块、最上面的一层有n 块砖,从上到下每层依次减少一块砖。每块砖

    都有一个分值,敲掉这块砖就能得到相应的分值,如下图所示。

    14 15  4  3  23
     33  33 76  2
       2   13 11
         22 23
           31
    

    如果你想敲掉第 i 层的第j 块砖的话,若i=1,你可以直接敲掉它;若i>1,则你必须先敲掉第 i-1 层的第j 和第j+1 块砖。

    你现在可以敲掉最多 m 块砖,求得分最多能有多少。

    1n501mn(n+1)/21≤n≤50,1≤m≤n*(n+1)/2


    color{red}{正解部分}

    若按行处理, 需要考虑这一行的每个元素是否可选, 但是 是否可选 这个问题不好处理 .

    但若按列处理, 可以发现从上往下敲的砖块是连续的,
    若从右往左处理, 又可以发现题目中的限制条件可以比较方便地处理 .

    于是从右往左按列处理,

    F[i,j,k]F[i, j, k] 表示 iiNN 列, 第 ii 列敲了 kk 个砖块, 总共敲了 jj 个砖块,

    F[i,j,k]=max{F[i+1,p,kj]+sum[i,j]}        (p  k1)F[i, j, k] = max{F[i+1, p, k-j] + sum[i, j]} (p geq k-1) .

    Ans=max(F[1,i,M])Ans = max(F[1, i, M])

    时间复杂度 O(N4)O(N^4) .


    color{red}{实现部分}

    1. 状态转移的来源一定要限制 !!!
    2. 注意 MM 的范围, F[][][]F[][][] 的第二维要开到 N2N^2 级别 !!!

    20pts100pts...20pts ightarrow 100pts 的区别...

    #include<bits/stdc++.h>
    #define reg register
    
    const int maxn = 55;
    
    int N;
    int M;
    int Ans;
    int A[maxn][maxn];
    int sum[maxn][maxn];
    int F[maxn][maxn*(maxn+1)/2][maxn];
    
    int main(){
            scanf("%d%d", &N, &M);
            for(reg int i = 1; i <= N; i ++)
                    for(reg int j = 1; j <= N-i+1; j ++) scanf("%d", &A[i][j]);
            for(reg int i = 1; i <= N; i ++)
                    for(reg int j = 1; j <= N-i+1; j ++) sum[i][j] = sum[i][j-1] + A[j][i];
            for(reg int i = N; i >= 1; i --) // cur_pos
                    for(reg int j = 1; j <= M; j ++) //tot
                            for(reg int k = 0; k <= j; k ++) //cur
                                    for(reg int p = std::max(0, k-1); p <= std::min(N-i, j-k); p ++) //last
                                            F[i][j][k] = std::max(F[i][j][k], F[i+1][j-k][p] + sum[i][k]);
            for(reg int i = 0; i <= N; i ++) Ans = std::max(Ans, F[1][M][i]);
            printf("%d
    ", Ans);
            return 0;
    }
    
    
  • 相关阅读:
    7-31 jmu-分段函数l (20 分)
    7-29 jmu-python-不同进制数 (10 分)
    7-28 摄氏温度转换华氏温度 (5 分)
    7-23 图的字典表示 (20 分)
    7-24 判断素数 (20 分)
    7-22 输出10个不重复的英文字母 (50 分)
    【转载】C#批量插入数据到Sqlserver中的三种方式
    天气预报api-汇总
    【转载】VS2015 + EF6连接MYSQL5.6
    【转摘】TFS上分支和标签的用法
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822522.html
Copyright © 2011-2022 走看看