[luogu 1880]石子合并
题目描述
在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。
试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分.
题解
我们目测一个dp方程
设f[i][j]表示i到j合并的最小(大)价值
那么
dp的时候按照区间长度递增来dp
首先最大值,根据单调性 肯定是从
和
转移来的
最小值的时候。这个东西满足四边形不等式
设表示使i~j最优的分界点
首先当时
满足
且
那么枚举中间点的时候只要从枚举到
复杂度证明。。
这样一坨可以两两抓出来消掉
就是这个<=n。复杂度就可证为
这是最小值的做法
- #include<map>
- #include<stack>
- #include<queue>
- #include<cstdio>
- #include<string>
- #include<vector>
- #include<cstring>
- #include<complex>
- #include<iostream>
- #include<assert.h>
- #include<algorithm>
- using namespace std;
- #define inf 1001001001
- #define infll 1001001001001001001LL
- #define ll long long
- #define dbg(vari) cerr<<#vari<<" = "<<(vari)<<endl
- #define gmax(a,b) (a)=max((a),(b))
- #define gmin(a,b) (a)=min((a),(b))
- #define Ri register int
- #define gc getchar()
- #define il inline
- il int read(){
- bool f=true;Ri x=0;char ch;while(!isdigit(ch=gc))if(ch=='-')f=false;while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=gc;}return f?x:-x;
- }
- #define gi read()
- #define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
- using namespace std;
- int n;
- int a[2333],s[2333],f[2333][2333],g[2333][2333];
- int main(){
- n=gi;
- for(int i=1;i<=n;i++) a[i]=a[i+n]=gi;
- for(int i=1;i<=n+n;i++) s[i]=s[i-1]+a[i];
- for(int i=1;i<=n+n;i++) f[i][i]=0,g[i][i]=i;
- for(int l=1;l<n;l++)
- for(int i=1;i<=2*n-l;i++){
- int j=l+i;
- f[i][j]=inf/2;
- for (int k=g[i][j-1];k<=g[i+1][j];k++)
- if (f[i][k-1]+f[k][j]<f[i][j]){
- f[i][j]=f[i][k-1]+f[k][j];
- g[i][j]=k;
- }
- f[i][j]+=s[j]-s[i-1];
- }
- int ans=inf;
- for(int i=1;i<=n;i++) ans=min(ans,f[i][i+n-1]);
- printf("%d\n",ans);
- for (int i=1;i<=2*n;i++) f[i][i]=0;
- for (int k=1;k<=n-1;k++)
- for (int i=1;i<=2*n-k;i++){
- int j=i+k;
- if (f[i][j-1]>f[i+1][j])
- f[i][j]=f[i][j-1]+s[j]-s[i-1];
- else
- f[i][j]=f[i+1][j]+s[j]-s[i-1];
- }
- ans=0;
- for (int i=1;i<=n;i++) ans=max(ans,f[i][i+n-1]);
- printf("%d\n",ans);
- return 0;
- }
[luogu 1880]石子合并的更多相关文章
- luogu P1880 石子合并
题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1 ...
- Luogu【P1880】石子合并(环形DP)
先放上luogu的石子合并题目链接 这是一道环形DP题,思想和能量项链很像,在预处理过程中的手法跟乘积最大相像. 用一个m[][]数组来存储石子数量,m[i][j]表示从第 i 堆石子到第 j 堆石子 ...
- 洛谷P1880 石子合并(区间DP)(环形DP)
To 洛谷.1880 石子合并 题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1 ...
- [LUOGU] P1880 [NOI1995]石子合并
题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1 ...
- NOI1995 石子合并 [Luogu P1880]
一道区间dp的模板题,这里主要记一下dp时环形数据的处理. 简略版:方法一:枚举分开的位置,将圈化为链,因此要做n次. 方法二:将链重复两次,即做一个2n-1长度的链,其中第i(i<=n)堆石子 ...
- 经典DP 洛谷p1880 石子合并
https://www.luogu.org/problemnew/show/P1880 题目 题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新 ...
- 【区间dp】- P1880 [NOI1995] 石子合并
记录一下第一道ac的区间dp 题目:P1880 [NOI1995] 石子合并 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 代码: #include <iostream> ...
- RQNOJ 490 环形石子合并
题目链接:https://www.rqnoj.cn/problem/490 题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一 ...
- codevs1048 石子合并
题目链接:http://codevs.cn/problem/1048/ 题目描述 Description 有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代 ...
随机推荐
- Eclipse中tomcat之后,tomcat的相关配置会被Eclipse重置
之前用MyEclipse,在tomcat的conf中修改了配置文件,启动就OK了. 现在改用Eclipse,发现改了,之后发现没有用,Eclipse重启tomcat之后,配置文件就被重置了. 众里寻他 ...
- 同一个tomcat多个web应用共享session
tomcat版本:apache-tomcat-6.0.29(次方tomcat6和tomcat7支持) 1.修改D:\apache-tomcat-6.0.29\conf\server.xml文件 ...
- C++ Stacks(堆栈)
C++ Stack(堆栈) 是一个容器类的改编,为程序员提供了堆栈的全部功能,——也就是说实现了一个先进后出(FILO)的数据结构. 操作 比较和分配堆栈 empty() 堆栈为空则返回真 pop() ...
- 在Java中怎样把数组转换为ArrayList?
翻译自:How to Convert Array to ArrayList in Java? 本文分析了Stack Overflow上最热门的的一个问题的答案,提问者获得了很多声望点,使得他得到了在S ...
- C#参数化SQL查询
//写一个存储过程 ALTER PROCEDURE dbo.Infosearch ( @bmid smallint = null, @xm varchar()=null, @xb varchar()= ...
- 例题6-5 Boxes in a line uVa12657
这道题目的解决方案是双向链表,数据结构本身并不复杂,但对于四种情况的处理不够细致,主要体现在以下几点: 分类讨论不全面,没有考虑特殊情况(本身不需要操作,需要互换的两元素相邻) 没有考虑状态4改变后对 ...
- composer安装yii2或者laravel报错
大概的信息就是提示让登陆github,然后就报错了 Could not fetch https://api.github.com/authorizations, enter your GitHub c ...
- 11g RAC R2 体系结构---Grid
基于agent的管理方式 从oracle 11.2开始出现了多用户的概念,oracle开始使用一组多线程的daemon来同时支持多个用户的使用.管理资源,这些daemon叫做Agent.这些Agent ...
- SQL Server 本地语言版本
要一些实验是往往喜欢使用英文的Windows 以及SQL Server ,但有时需要使用中文的环境方便理解.中文的SQL Server 不能被安装在英文的Windows 系统上. 根据文档可得知以下兼 ...
- python之参数
1. 参数传递有2种方式: 按位置传递, 按关键字传递. 2. 形参可以定义默认值, 可以用*收集元组, 可以用**收集字典. 其中, (1)指定默认值的形参可不接收实参. (2)指定*的形参用元组收 ...