zoukankan      html  css  js  c++  java
  • P1063 能量项链 【区间dp】

    P1063 能量项链

    输入输出样例

    输入 #1
    4
    2 3 5 10
    
    输出 #1
    710

    说明/提示

    NOIP 2006 提高组 第一题

    思路

      很像石子合并的一道题,只不过把获得的价值给改了一下。

      如果有两堆石子可以合并,分别为 ( i , k ) , ( k + 1, j ) ,获得的价值为 head [ i ] * tail [ k ] * tail [ j ]。

      然后像石子合并那样做就可以了。

    CODE

    #include <bits/stdc++.h>
    #define dbg(x) cout << #x << "=" << x << endl
    #define eps 1e-8
    #define pi acos(-1.0)

    using namespace std;
    typedef long long LL;

    const int inf = 0x3f3f3f3f;

    template<class T>inline void read(&res)
    {
        char c;T flag=1;
        while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
        while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
    }

    namespace _buff {
        const size_t BUFF = 1 << 19;
        char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
        char getc() {
            if (ib == ie) {
                ib = ibuf;
                ie = ibuf + fread(ibuf, 1, BUFF, stdin);
            }
            return ib == ie ? -1 : *ib++;
        }
    }

    int qread() {
        using namespace _buff;
        int ret = 0;
        bool pos = true;
        char c = getc();
        for (; (< '0' || c > '9') && c != '-'; c = getc()) {
            assert(~c);
        }
        if (== '-') {
            pos = false;
            c = getc();
        }
        for (; c >= '0' && c <= '9'; c = getc()) {
            ret = (ret << 3) + (ret << 1) + (^ 48);
        }
        return pos ? ret : -ret;
    }

    const int maxn = 307;

    int n;

    int head[maxn];
    int tail[maxn];
    int f[maxn][maxn];

    int main()
    {
        read(n);
        for ( int i = 1; i <= n; ++) {
            read(head[i]);
            head[+ i] = head[i];
        }
        for ( int i = 1; i <= 2 * n - 1; ++) {
            tail[i] = head[+ 1];
        }
        int ans = -1;
        tail[2 * n] = head[1];
        for ( int z = 1; z <= n - 1; ++) {//!枚举区间长度
            for ( int i = 1; i <= 2 * n - z; ++) {
                int j = i + z;
                for ( int k = i; k <= j - 1; ++) {
                    f[i][j] = max(f[i][j], f[i][k] + f[+ 1][j] + head[i] * tail[k] * tail[j]);
                    ans = max(ans, f[i][j]);
                }
            }
        }
        cout << ans << endl;
        return 0;
    }
  • 相关阅读:
    scala之伴生对象的继承
    scala之伴生对象说明
    “Failed to install the following Android SDK packages as some licences have not been accepted” 错误
    PATH 环境变量重复问题解决
    Ubuntu 18.04 配置java环境
    JDBC的基本使用2
    DCL的基本语法(授权)
    ZJNU 1374
    ZJNU 2184
    ZJNU 1334
  • 原文地址:https://www.cnblogs.com/orangeko/p/12540636.html
Copyright © 2011-2022 走看看