zoukankan      html  css  js  c++  java
  • Luogu-P1063 能量项链

    题目

    题目链接

     

    测试得分:  100

    主要算法 :  动态规划,区间DP(环状DP)

    题干:

        环状区间DP板子题

    应试策略:

    1. 确定状态f[i][j]表示的是合并i-j这几堆吸盘释放的能量的最大值 
    2. 枚举区间长度FORa(l,1,n)
    3. 枚举区间开头for(int i=1,in=2*n-l+1;i<=in;i++)
    4. 状态转移f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]+a[i].head*a[k].tail*a[j].tail);
    5. 更新答案 if(l==n) ans=max(ans,f[i][i+n-1]);
    #include<stdio.h>
    #include<stdlib.h>
    #define FORa(i,s,e) for(int i=s;i<=e;i++)
    #define FORs(i,s,e) for(int i=s;i>=e;i--)
    
    using namespace std;
    
    const int N=100;
    struct Node{
        int head,tail;
    }a[2*N+2]; 
    int n,ans,f[2*N+2][2*N+2];//f[i][j]表示的是合并i-j这几堆吸盘释放的能量的最大值 
    inline int max(int fa,int fb){return fa>fb?fa:fb;}
    int main()
    {
        scanf("%d",&n);
        FORa(i,1,n) scanf("%d",&a[i].head),a[i+n].head=a[i].head;
        for(int i=1;i<2*n;i++) a[i].tail=a[i+1].head;
        a[2*n].tail=a[1].head;
        FORa(l,1,n)//枚举处理吸盘长度 
        {
            for(int i=1,in=2*n-l+1;i<=in;i++)//枚举开头 
            {
                for(int k=i,j=i+l;k<j;k++)//状态转移 
                    f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]+a[i].head*a[k].tail*a[j].tail);
                if(l==n) ans=max(ans,f[i][i+n-1]);//更新答案 
            }
        }
        printf("%d",ans);
        return 0;
    }
    /*4
    2 3 5 10*/

    总结:

    •   初值
    •   边界
    •   状态转移

  • 相关阅读:
    UBI FAQ and HOWTO
    Is an MTD device a block device or a char device?
    使用apt-mirror建立本地debian仓库源
    在SpringMVC中获取request对象的几种方式
    spring mvc提交日期类型参数
    Java 获取指定日期的方法汇总
    CentOS 7 安装tomcat
    CentOS 7 安装和配置JDK
    CentOS7 yum 安装git
    Java List合并去重
  • 原文地址:https://www.cnblogs.com/SeanOcean/p/11303440.html
Copyright © 2011-2022 走看看