合并石子
来源:互联网 发布:lnmp php探针 编辑:程序博客网 时间:2024/05/22 17:49
题目
合并石子 https://www.luogu.org/problem/show?pid=1880
题目描述
在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。
试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分.
输入输出格式
输入格式:
数据的第1行试正整数N,1≤N≤100,表示有N堆石子.第2行有N个数,分别表示每堆石子的个数.
输出格式:
输出共2行,第1行为最小得分,第2行为最大得分.
输入输出样例
输入样例#1:
4
4 5 9 4
输出样例#1:
43
54
思路
不难理解我们可以想象一个圆环的数据结构,但是圆环这样的结构太难处理,我们可以将它线性化。首先第一步就是破环为线。
4 5 9 4
扩充成 4 5 9 4 4 5 9 ,规定每次遍历的长度只能是4个。
我们写个dfs(l,r)函数,返回l到r之间的最小得分。
在主函数里面 我们dfs(0,3) dfs(1,4) dfs(2,5)…等等
最后寻找上面中最小的值时多少 就是我们呢要求得最小得分。
代码
#include<list>#include<vector>#include<math.h>#include<iostream>#include<algorithm>using namespace std;#define MAXSIZE 15001#define INF 0xffint N = 0;int minAns = 0xffff;int maxAns = 0;std::vector<int> inputVector;int dpDfs[INF][INF] = { 0 };int dpDfs2[INF][INF] = { 0 };int dfs(int l, int r);int sum(int l, int r);// return : [l,r]区间内最小的得分int dfs(int l,int r){ if (dpDfs[l][r] != 0) { return dpDfs[l][r]; } if (l == r) { return 0; } if (l + 1 == r) { return inputVector[l] + inputVector[r]; } int LocMinAns = 0xffff; for (int ti = l; ti < r; ++ti) { int temp = 0; temp = dfs(l, ti) + dfs(ti + 1, r) + sum(l, r); LocMinAns = min(LocMinAns, temp); } dpDfs[l][r] = LocMinAns; return LocMinAns;}// 求区间最大值int dfs2(int l, int r){ if (dpDfs2[l][r] != 0) { return dpDfs2[l][r]; } if (l == r) { return 0; } if (l + 1 == r) { return inputVector[l] + inputVector[r]; } int LocMaxAns = 0; for (int ti = l; ti < r; ++ti) { int temp = 0; temp = dfs2(l, ti) + dfs2(ti + 1, r) + sum(l, r); LocMaxAns = max(LocMaxAns, temp); } dpDfs2[l][r] = LocMaxAns; return LocMaxAns;}int sum(int l, int r){ int sumAns = 0; for (int i = l; i <= r; ++i) { sumAns += inputVector[i]; } return sumAns;}int main(){ cin >> N; // 读入N个数据 while (N--) { int temp = 0; cin >> temp; inputVector.push_back(temp); } int size = 0; size = inputVector.size(); // 1 2 3 4 5 4 3 2 1 如此扩充n-1个数字 for (int i = 0; i<size-1; ++i) { inputVector.push_back(inputVector[i]); } for (int l = 0; l < inputVector.size()/2; l++) { int temp = 0; int r = l + inputVector.size() / 2; temp = dfs(l, r); minAns = min(temp, minAns); temp = 0; temp = dfs2(l, r); maxAns = max(temp, maxAns); } cout << minAns<<endl; cout << maxAns; return 0;}
阅读全文
0 0
- 石子-石子合并
- 石子合并
- 石子合并
- 石子合并
- 石子合并
- 石子合并
- 石子合并
- 【石子合并】
- 合并石子
- 石子合并
- 石子合并
- 石子合并
- 石子合并
- 石子合并
- 石子合并
- 合并石子
- 石子合并
- 合并石子
- Linux C 中的一些基础命令
- 作为一位程序员必须掌握的技术
- Spring注入Date类型的属性,自定义Date属性编辑器
- 腾讯AI Lab副主任俞栋:语音识别研究的四大前沿方向
- Spring MVC 积累-不断更新
- 合并石子
- Java网络编程概述
- JVM学习及堆参数含义
- Leetcode(14)
- C++重载赋值运算符
- UML统一建模语言
- 谈谈#define xxxx(x,y) x##y
- Linux文本处理工具grep命令详解
- Node.js Express框架