DP——Luogu1437 [HNOI2004]敲砖块

题面:Luogu1437
首先这个三角形不满足dp的无后效性
那么我们把这个三角形按左上角逆时针旋转90度一下
比如样例
2 2 3 4
8 2 7
2 3
49
转成
4
3 7
2 2 3
2 8 2 49
这样就可以DP了
定义状态:f[i][j][k]表示取了第i行第j列取了k块的最大值
因为取了第i行第j列以后第i行前面j个砖块全部会被取掉,所以维护一个前缀和s[i][j]表示第i行前j个的总值
那么状态转移方程就是:
f[i][j][k]=max(f[i-1][l][k-j])+s[i][j](l从j-1到i-1枚举)
然后取max
还有那个j=0的时候需要搞一下,否则65分

#include<bits/stdc++.h>
using namespace std;
int f[52][52][5001]={0},a[51][51];
int main()
{
    int n,m;scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)for(int j=n;j>=i;j--)scanf("%d",&a[j][i]);
    for(int i=1;i<=n;i++)for(int j=1;j<=i;j++)a[i][j]+=a[i][j-1];
    for(int i=1;i<=n;i++)
        for(int j=0;j<=i;j++)
            for(int k=j*(j+1)/2;k<=i*(i-1)/2+j;k++)
                for(int l=j-1;l<=i-1;l++)f[i][j][k]=max(f[i][j][k],f[i-1][l][k-j]+a[i][j]);
    int ans=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=i;j++)ans=max(ans,f[i][j][m]);
    printf("%d",ans);
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值