P3146 [USACO16OPEN]248 (区间DP)

题目描述

  给定一个1*n的地图,在里面玩2048,每次可以合并相邻两个(数值范围1-40),问最大能合出多少。注意合并后的数值并非加倍而是+1,例如2与2合并后的数值为3.

  这道题的思路:

    状态:

  f[i][j] 代表当前 i -> j的最大值 . 初始的f[i][i] = a[i].

  然后枚举点 1 -> n-1 到 n 的区间.

  然后中间再枚举断点 k.

    方程就是 f[i][j] = max(f[k+1][j]+1,f[i][j]);

 约束条件:

  当且仅当两个区间所得到的最大值相同的时候才能往后更新. 

   代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int f[250][250],a[250];
int n,maxx,k,ans=-1;
int main()
{
    int i,tmp,j,t;
    scanf("%d",&n);
    for (i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        f[i][i]=a[i];
    }
    for (i=n-1;i>=1;i--)
        for (j=i+1;j<=n;j++)
            for (k=i;k<=j-1;k++)
            {
                if (f[i][k]==f[k+1][j])
                    f[i][j]=max(f[k+1][j]+1,f[i][j]);
                ans=max(ans,f[i][j]);
            }
    printf("%d",ans);
}
原文地址:https://www.cnblogs.com/Kv-Stalin/p/8869317.html