• [P1880] [NOI1995]石子合并(环形dp)


    题目描述

    在一个圆形操场的四周摆放 (N) 堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。

    试设计出一个算法,计算出将(N)堆石子合并成 (1) 堆的最小得分和最大得分。

    输入格式

    数据的第 (1) 行是正整数 (N),表示有 (N) 堆石子。

    (2) 行有 (N) 个整数,第 (i) 个整数 (a_i) 表示第 (i) 堆石子的个数。

    输出格式

    输出共 (2) 行,第 (1) 行为最小得分,第 (2) 行为最大得分。

    输入输出样例

    输入 #1

    4
    4 5 9 4
    

    输出 #1

    43
    54
    

    说明/提示

    (1≤N≤100,0≤ai≤200。)

    【思路】

    拆环,把链的长度延长到(2n), 区间dp做法,最后枚举左端点取其中最大/最小的结果。

    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <list>
    #include <map>
    #include <iostream>
    #include <iomanip>
    #include <queue>
    #include <set>
    #include <stack>
    #include <string>
    #include <unordered_map>
    #include <vector>
    #define LL long long
    #define inf 0x3f3f3f3f
    #define INF 0x3f3f3f3f3f3f
    #define PI 3.1415926535898
    #define F first
    #define S second
    #define endl '
    '
    #define lson  rt << 1
    #define rson  rt << 1 | 1
    #define f(x, y, z) for (LL x = (y), __ = (z); x < __; ++x)
    #define _rep(i, a, b) for (LL i = (a); i <= (b); ++i)
    using namespace std;
    
    const int maxn = 207;
    const int maxm = 2e4 + 7;
    const int mod = 19650827;
    int n;
    int a[maxn], dpmx[maxn][maxn], dpmn[maxn][maxn], sum[maxn];
    
    int main()
    {
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    	cin >> n;
    	memset(dpmx, 0, sizeof(dpmx));
    	memset(dpmn, inf, sizeof(dpmn));
    	_rep(i, 1, n)
    	{
    		cin >> a[i];
    		a[i + n] = a[i];
    	}
    	_rep(i, 1, 2 * n)
    	{
    		sum[i] = sum[i - 1] + a[i];
    		dpmn[i][i] = 0;
    	}
    	_rep(len, 1, n)
    	{
    		_rep(l, 1, n * 2 - len)
    		{
    			int r = l + len;
    			_rep(k, l, r - 1)
    			{
    				dpmx[l][r] = max(dpmx[l][r], dpmx[l][k] + dpmx[k + 1][r] + sum[r] - sum[l - 1]);
    				dpmn[l][r] = min(dpmn[l][r], dpmn[l][k] + dpmn[k + 1][r] + sum[r] - sum[l - 1]);
    			}
    		}
    	}
    	int mx = 0, mn = inf;
    	_rep(i, 1, n)
    	{
    		mx = max(mx, dpmx[i][i + n - 1]);
    		mn = min(mn, dpmn[i][i + n - 1]);
    	}
    	cout << mn << endl << mx << endl;
    }
    
  • 相关阅读:
    在ASP.NET中把数据POST到其他页面
    在网页中使用javascript打开没有最大化、最小化和关闭按钮的窗口
    怎么找回被删并清空了回收站的文件
    域控制器的安装步骤二——把客户机加入到域
    升级和卸载域AD:实现域网络管理二
    不用设置BIOS,也能让光驱启动电脑!
    老版(旧版)封神榜片头,片尾曲
    域控制器的安装步骤一
    SEO面试试题
    如何将客户机添加到域?
  • 原文地址:https://www.cnblogs.com/hfcdyp/p/13455311.html
Copyright © 2020-2023  润新知