ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[复习资料.PDF]环形石子合并(DP)

2021-02-15 15:03:28  阅读:160  来源: 互联网

标签:202 const Min int sum 石子 复习资料 PDF DP


discription:
有一圈石子, 每堆重量为w[i], 每次操作合并相邻的石子, 得分为两堆石子的重量之和. 问将这一圈n个石子合并n-1次成一堆的最高和最低得分.
solution:
将环展开成链:\(12345 \rightarrow 1234512345\), 复制后, 双倍链中有环的所有排列.
前缀和预处理获取\(i到j\)的重量和\(sum(i,j)\)
DP:
\(设起点i,终点j的最少得分为f[i,j], 则f[i,j]=\begin{cases} min_{i\le k<j}(f[i,k]+f[k+1,j]+sum(i,j)) \\ 0, \ when \ \ i=j \end{cases}\)
将区间长度\(d\)作为外层循环, 以建立递推.
code:

#include<cstdio>
#include<cstring>
const int INF(1000000000);
int M[202][202], m[202][202], w[202], sum[202];
inline int s(const int& i, const int& j) { return sum[j] - sum[i - 1]; }
int main() {
	int n;
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", w + i);
		w[i + n] = w[i];
	}
	for (int i = 1; i < (n << 1); ++i)sum[i] = sum[i - 1] + w[i];
	for (int d = 1; d < n; ++d) 
		for (int i = 1, j = i + d; j<(n<<1); j = ++i + d) {
			M[i][j] = 0, m[i][j] = INF;
			for (int k = i; k < j; ++k) {
				if (M[i][k] + M[k + 1][j] + s(i, j) > M[i][j])M[i][j] = M[i][k] + M[k + 1][j] + s(i, j);
				if (m[i][k] + m[k + 1][j] + s(i, j) < m[i][j])m[i][j] = m[i][k] + m[k + 1][j] + s(i, j);
			}
		}
	int Max=0, Min=INF;
	for (int i = 1; i <= n; ++i) {
		if (Max < M[i][i + n - 1])Max = M[i][i + n - 1];
		if (Min > m[i][i + n - 1])Min = m[i][i + n - 1];
	}
	printf("%d %d\n", Max, Min);
}

标签:202,const,Min,int,sum,石子,复习资料,PDF,DP
来源: https://www.cnblogs.com/dwt2021/p/14403721.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有