yzoj P2343&羅区P1437は、[HNOI2004]レンガをノック

問題の意味

レンガのN層が上から下へレンガ減少都度、油Nレンガの最上層に前記凹部内に配置されます。図に示すように、各ブリックのスコアを有し、このレンガは、対応する値をノック得ることができます。

あなたが最初のレンガ層I jをノックしたい場合はI = 1ならば、その後、あなたはそれをノックアウトすることができます; I> 1なら、あなたは私-1番目の層とj-jは+をノックダウンする必要があります。 1個のレンガ。

あなたは今ではほとんどの数を獲得しているしようとしている、Mレンガまでノックすることができます。

問題Dpは、ラインDPによってラインを考えるようになった発見された、しかし、選択し[i、j]が選ぶだろう[I-1、jは+ 1 ] と[私は、j]は上記のすべてのボックスは、何の後遺症が満たされていないんようですセックスは、どのようにそれを行うには?
我々は、このようなファイルの入力を見つけたら

4 5
2 2 3 4
8 2 7
2 3
49

私たちは、そう何の後遺症n列からDPに、A DPは不可能ではないと考えるために行くことができ、我々は、Fの状態を定義することができます[I] [J] [k]はi番目の列に電流を表しj番目から選択されますK選挙、状態遷移方程式の合計

F [I] [J] [K] = MAX(F [I + 1] [T] [KJ] + S [i]は[J]、F [i]は[J] [K])

T> = J-1 && T <= NI

S [i] [j]は、i番目の前に、j番目の列を表し、

コード

#include<bits/stdc++.h>
using namespace std;
int n,m,ans,f[55][55][3000],a[55][55],s[55][55];
int main(){
    scanf("%d %d",&n,&m);
    memset(f,-0x3f,sizeof(f));
    f[n+1][0][0]=0;
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n-i+1;++j){
            scanf("%d",&a[i][j]);
        }
    }   
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n-i+1;++j){
            s[j][i]=s[j][i-1]+a[i][j];
        }
    }
    for(int i=n;i>=1;--i){
        for(int j=0;j<=n-i+1;++j){
            for(int k=j;k<=m;++k){
                for(int t=max(j-1,0);t<=n-i;++t){
                    f[i][j][k]=max(f[i+1][t][k-j]+s[i][j],f[i][j][k]);
                }
            }
        }
    }
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n-i+1;++j){
            ans=max(ans,f[i][j][m]);
        }
    }
    printf("%d",ans);
    return 0;
}

おすすめ

転載: www.cnblogs.com/donkey2603089141/p/11416629.html