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

    原题链接:https://www.luogu.org/problem/show?pid=1063

    区间DP题,即把整个问题划分成若干个小区间求解。

    这个题细节太多了。。。

    最后犯了一个傻逼性错误,数组开小了,死活过不了最后两个点

    现在洛谷关站维护中,所以这题我在codevs上跑的。

    思路是用f[i][j]表示这条项链上的珠子从i号位合到j号位的最大价值。状态转移方程为f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]+a[i]*a[k+1]*a[j+1])。

    不过题意说到数据是一个环,这里有两种处理方式。

    一种是绝大多数题解里用的化环为链的方法将它变成链状,还有的题解是计算时取模,把这个数据就当成环来看待。

    我写的也是化环为链,即在记录a数组的时候把数组开二倍大,i+n处也存储i位置的值,这样就可以模拟出中间的接口。

    首先有一个i枚举到2n,枚举的是区间大小,然后有一个l枚举的是左端点,其应该满足l+i-1<2*N,也就是不让右端点越界 。

    然后设一个变量r为l+i-1,这个代表的是右端点,然后有一个k从l枚举到r,枚举的是所谓断点。断点实际上就是我们要试图合并的位置。

    进行转移,然后枚举1到n处理ans为max(f[i][i+n-1]),最后输出ans就好。

    参考代码:

     1 #include <iostream>
     2 #define maxn 300
     3 using namespace std;
     4 int f[maxn][maxn];
     5 int a[maxn];
     6 int n,ans;
     7 
     8 int main(){
     9     cin >> n;
    10     for (int i=1;i<=n;i++){
    11         cin >> a[i];
    12         a[i+n] = a[i];
    13     }
    14     for (int i=2;i<=2*n;i++) 
    15         for (int l=1;l+i-1<=2*n;l++){ 
    16           int r=l+i-1;
    17           for (int k=l;k<=r;k++)
    18               f[l][r]=max(f[l][r],f[l][k]+f[k+1][r]+a[l]*a[k+1]*a[r+1]);
    19       }
    20       
    21     for (int i=1;i<=n;i++)
    22         ans = max(ans,f[i][i+n-1]);
    23     cout << ans << endl;
    24     return 0;        
    25 }
  • 相关阅读:
    Binary Tree Maximum Path Sum
    ZigZag Conversion
    Longest Common Prefix
    Reverse Linked List II
    Populating Next Right Pointers in Each Node
    Populating Next Right Pointers in Each Node II
    Rotate List
    Path Sum II
    [Leetcode]-- Gray Code
    Subsets II
  • 原文地址:https://www.cnblogs.com/OIerShawnZhou/p/7572143.html
Copyright © 2011-2022 走看看