• c_aw_能量项链(破环成链)


    对于相邻的两颗珠子,前一颗珠子的尾标记一定等于后一颗珠子的头标记。
    因为只有这样,通过吸盘(吸盘是Mars人吸收能量的一种器官)的作用,这两颗珠子才能聚合成一颗珠子,同时释放出可以被吸盘吸收的能量。
    如果前一颗能量珠的头标记为m,尾标记为r,后一颗能量珠的头标记为 r,尾标记为 n,则聚合后释放的能量为 mrn(Mars单位),新产生的珠子的头标记为 m,尾标记为 n
    需要时,Mars人就用吸盘夹住相邻的两颗珠子,通过聚合得到能量,直到项链上只剩下一颗珠子为止。
    例如:设N=4,4颗珠子的头标记与尾标记依次为(2,3) (3,5) (5,10) (10,2)。
    我们用记号⊕表示两颗珠子的聚合操作,(j⊕k)表示第 j,k 两颗珠子聚合后所释放的能量。则
    第4、1两颗珠子聚合后释放的能量为:(4⊕1)=1023=60。
    这一串项链可以得到最优值的一个聚合顺序所释放的总能量为((4⊕1)⊕2)⊕3)= 1023+1035+10510=710。

    输入样例:
    4
    2 3 5 10
    输出样例:
    710
    

    方法一:区间dp

    加以修饰的环形石子合并...

    • 定义状态
      • f[l][r] 表示将区间[l,r] 这一段合并得到的最大能量值
    • 思考初始化:
      • f[l][r]=0
    • 思考状态转移方程
      • f[l][r]=f[l][i]+f[i+1][r]+A[l]A[i]A[r]
    • 思考输出:max(f[l][l+n]),l∈[1,n]
    #include<bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    const int N=205;
    ll f[N][N], A[N];
    
    ll dfs(int l, int r) {
        if (l>=r) return 0;
        if (f[l][r]) return f[l][r];
        ll t=0;
        for (int i=l+1; i<r; i++) {
            t=max(t, dfs(l,i)+dfs(i,r)+A[l]*A[i]*A[r]);
        } 
        return f[l][r]=t;
    }
    int main() {
        std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        ll n, ans=0; cin>>n;
        for (int i=1; i<=n; i++) cin>>A[i], A[i+n]=A[i];
        for (int i=1; i<=n; i++) ans=max(ans, dfs(i, i+n));
        cout << ans;
        return 0;
    }
    

    复杂度分析

    • Time\(O(n^3)\)
    • Space\(O(n^2)\)
  • 相关阅读:
    Max Function
    动态语句语法:EXEC\SP_EXECUTESQL语法(转载)
    [转帖]在SQL SERVER中实现RSA加密算法
    [转]C#实现QQ接口软件QQ的HTTP接口协议探究
    用一条sql语句删除表中所相同的记录
    SQL Server存储过程 对数组参数的循环处理
    在WinDBG中, 使用.shell命令来搜索字符串
    SharePoint提供的一些javascript函数
    IP协议里的Time To Live(TTL)
    SharePoint Application Pool的推荐设置
  • 原文地址:https://www.cnblogs.com/wdt1/p/13660419.html
Copyright © 2020-2023  润新知