【HNOI2004】敲砖块(动态规划)

越来越懒了,不想粘题目

题解

样例的输入是个很好的提醒,
把他往左边对齐之后
如果要打掉某个位置,那么必须要打掉右上方的所有砖
然后就很明显的一个DP了。。。。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
using namespace std;
#define MAX 55
#define INF 100000000
inline int read()
{
    int x=0,t=1;char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=-1,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return x*t;
}
int N,M;
int g[MAX][MAX],s[MAX][MAX];
int f[MAX][MAX][2500];
int Ans;
int main()
{
    N=read();M=read();
    for(int i=1;i<=N;++i)
        for(int j=1;j<=(N-i+1);++j)
            g[i][j]=read();
    for(int i=1;i<=N;++i)
        for(int j=1;j<=(N-i+1);++j)
            s[i][j]=s[i][j-1]+g[j][i];
    for(int i=1;i<=N+1;++i)
        for(int j=0;j<=N+1;++j)
            for(int k=0;k<=M;++k)
                f[i][j][k]=-INF;
    f[N+1][0][0]=0;
    for(int i=N;i;--i)
    {
        for(int j=0;j<=(N-i+1);++j)
        {
            for(int k=j;k<=M;++k)
            {
                for(int l=max(0,j-1);l<=(N-i);++l)
                {
                    if(f[i+1][l][k-j]!=-INF)
                        f[i][j][k]=max(f[i][j][k],f[i+1][l][k-j]+s[i][j]);
                }
                Ans=max(Ans,f[i][j][k]);
            }
        }
    }
    printf("%d
",Ans);
    return 0;
}

原文地址:https://www.cnblogs.com/cjyyb/p/7623745.html