【HNOI2004】 敲磚塊 動態規劃

題目描述:

在一個凹槽中放置了 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 塊磚,求得分最多能有多少。

輸入輸出格式

輸入格式:
輸入文件的第一行爲兩個正整數 n 和m;接下來n 行,描述這n 層磚塊上的分值a[i][j],滿足

0≤a[i][j]≤100。

對於 100%的數據,滿足1≤n≤50,1≤m≤n*(n+1)/2;

輸出格式:
輸出文件僅一行爲一個正整數,表示被敲掉磚塊的最大價值總和。

輸入輸出樣例

輸入樣例#1:
4 5
2 2 3 4
8 2 7
2 3
49
輸出樣例#1:
19

題解:
首先將磚塊全部左對齊,變成一個直角三角形的模樣。
可以得出如下結論:
1、每一列必須敲到由上到下的若干磚塊。
2、如果某一列敲掉了k個磚塊,那麼其右邊的那一列至少敲掉了k-1個磚塊。
f[i][j][k] 表示從右到左已經敲到了第i列,其中第i列敲掉了j個磚塊且總共敲掉了k個磚塊的最大得分,那麼轉移方程爲f[i][j][k]=maxf[i+1][v][kj]+a[1][i]+a[2][i]++a[j][i](v>=j1)
最終答案爲maxf[i][j][k]

代碼:

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int f[56][56][506];
int a[56][56],ans=0;
int n,m;
int get()
{
    int x=0,p=1;
    char c;
    c=getchar();
    if (c==' ') return x*p;
    while (c<'0'||c>'9') {if (c=='-') p=-1;c=getchar();}
    while (c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
    return x*p;
}
int main()
{
    int i,j,k,v;
    n=get();m=get();
    for (i=1;i<=n;i++)
        for (j=1;j<=n-i+1;j++)
        {
            a[i][j]=get();
//          f[n-i+1][j].s=a[n-i+1][j];
//          f[n-i+1][j].s=a[n-i+1][j];
        }
    memset(f,-127,sizeof(f));
    f[n+1][0][0]=0;
    for (i=n;i>=1;i--)
        for (j=0;j<=n-i+1;j++)
            for (k=j;k<=m;k++)
            {
                for (v=j-1;v<=n-i;v++)
                    if (f[i+1][v][k-j]!=-1&&k-j>=0)
                    f[i][j][k]=max(f[i][j][k],f[i+1][v][k-j]);
//              f[i][j].w=f[i-1][j].w+f[i-1][j+1].w+1;
//              f[i][j][0][k]=max(f[i-1][j][0][k],f[i-1][j][0][k]);
//              printf("f[%d][%d]=%d    ",i,j,f[i][j].s);
//              printf("f[%d][%d]=%d\n",i,j,f[i][j].w);
//              printf("f[%d][%d][0][%d]=%d\n",i,j,k,f[i][j][0][k]);
                for (v=1;v<=j;v++)
                    f[i][j][k]+=a[v][i];
                ans=max(ans,f[i][j][k]);
            }
    printf("%d",ans);
}
發佈了79 篇原創文章 · 獲贊 32 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章