zoukankan      html  css  js  c++  java
  • 洛谷1063 +区间dp(经典问题)

    题目网址:https://www.luogu.com.cn/problem/P1063

    题意大致是:给定一个序列An,第i个元组表示为(Ai,Ai+1),序列位置不变,当合并一个区间[l,l+1]时开销是Al*Al+1*Al+2,问合并整个序列的最大开销。一看就是区间dp,顺便借助记忆化减少搜索的冗余。题目中的项链是环状的,可以通过拼接相同的序列在元序列之后构造出一条链状的序列。这个问题与矩阵链相乘有点相似。代码如下:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef unsigned int ui;
     4 typedef long long ll;
     5 typedef unsigned long long ull;
     6 #define pf printf
     7 #define mem(a) memset(a,0,sizeof(a))
     8 #define prime1 1e9+7
     9 #define prime2 1e9+9
    10 #define scand(x) scanf("%llf",&x) 
    11 #define f(i,a,b) for(int i=a;i<=b;i++)
    12 #define scan(a) scanf("%d",&a)
    13 #define dbg(args) cout<<#args<<":"<<args<<endl;
    14 #define pb(i) push_back(i)
    15 #define ppb(x) pop_back(x)
    16 #define maxn 300
    17 int n,m,t,a[maxn],ans=0;
    18 int dp[maxn][maxn];
    19 int dfs(int l,int r)//计算[l,r]区间合并的开销 
    20 {
    21     if(l==r)return 0;//单个的没有开销 
    22     if(dp[l][r])return dp[l][r];
    23     if(l==r-1) return a[l]*a[l+1]*a[r+1];//最小子问题,合并区间长度为2的两个 
    24     int res=0;
    25     f(i,l,r-1)
    26     {
    27         res=max(res,dfs(l,i)+dfs(i+1,r)+a[l]*a[i+1]*a[r+1]);//枚举两个子区间,有点分治的意味 
    28     }
    29     return dp[l][r]=res;
    30 }
    31 int main()
    32 {
    33     //freopen("input.txt","r",stdin);
    34     //freopen("output.txt","w",stdout);
    35     std::ios::sync_with_stdio(false);
    36     scan(n);
    37     mem(dp);
    38     f(i,1,n)
    39     {
    40         scan(a[i]);
    41         a[i+n]=a[i];//环状变为链状 
    42     }
    43     f(i,1,n)
    44     {
    45         ans=max(ans,dfs(i,n+i-1));
    46     }
    47     pf("%d",ans);
    48  } 
  • 相关阅读:
    SQL Server逻辑读、预读和物理读
    SQL Server 视图
    SQL Server存储机制
    SQLServer
    数据库配置问题整理贴
    分析存储过程重编译的起因以及避免
    存储过程重编译的优点、缺点、确定引发语句
    查询反模式
    查询反模式
    状压DP的总结
  • 原文地址:https://www.cnblogs.com/randy-lo/p/12388910.html
Copyright © 2011-2022 走看看