小菜吃鸡腿

小菜吃鸡腿

特别裸的区间 dp ,而且之前还写过一样的题,居然没写出来,55555,主要还是因为把区间 dp 的思路给忘了

区间 dp 的主要思路:假设有一段区间[l,r],当lr缩为最小的单位区间的时候肯定会有一个初始值,这个是无疑的,然后当[l,r]的区间长度扩大的时候,尝试去在区间内找一个k使得这整个区间[l,r]的值为最大(即满足题目要求)。

整理一下区间 dp 的几个步骤:

总共三个for

第一个 遍历区间长度len

第二个遍历起始位置即得出lr的坐标,即可得到区间[l,r]

第三个遍历区间[l,r]的切分点k,从而找到最满足条件的dp[l][r](最大值或最小值)

代码:

// Created by CAD on 2019/8/21.
#include <bits/stdc++.h>
#define ll long long
using namespace std;

ll dp[60][60];
int w[55];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;cin>>n;
    for(int i=1;i<=n;++i) cin>>w[i];
    for(int k=3;k<=n;++k)
        {
            for (int l=1; l+k-1<=n; ++l)
            {
                int r=l+k-1;
                for(int i=l+1;i<=r-1;++i)
                    dp[l][r]=max(dp[l][r],dp[l][i]+dp[i][r]+w[l]*w[r]);
            }
        }
    cout<<dp[1][n]<<endl;
    return 0;
}

递归版本:

// Created by CAD on 2019/8/21.
#include <bits/stdc++.h>
#define ll long long
using namespace std;

ll dp[60][60];
int w[55];
ll dfs(int l,int r)
{
    ll &ret=dp[l][r];
    if(l>r) return 0;
    if(ret) return ret;
    for(int k=l+1;k<=r-1;++k)
        ret=max(ret,dfs(l,k)+dfs(k,r)+w[l]*w[r]);
    return ret;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;cin>>n;
    for(int i=1;i<=n;++i) cin>>w[i];
    cout<<dfs(1,n)<<endl;
    return 0;
}

貌似感觉递归写起来更加方便些

转载于:https://www.cnblogs.com/CADCADCAD/p/11388071.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值