codeforces #334 D. Babaei and Birthday Cake (线段树或者dp+二分)

本文介绍了解决一道编程题目的两种方法:一种利用set维护动态规划状态,另一种使用线段树结合离散化技术。这两种方法都旨在寻找一个序列的严格升序子序列,使得该子序列的元素之和最大。

题目:http://codeforces.com/contest/629/problem/D

题意:给定一个长度为n(n<100000)的序列,求找一个严格升序的子序列使得子序列的和最大。

分析:

定义dp[sum]表示和为sum,以dp[sum]结尾的最小体积。(类似最长上升子序列的做法)

我们发现sum越小,那么dp[sum]就越小,否则,dp[sum]不够优,就不满足定义。

所以dp[sum]数组是具有单调性的。

维护dp[sum]数组的话,用一个set维护。

代码:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 1ll<<62;
const LL MINT = ~0u>>1;
const int maxn = 123456;
struct node
{
	LL dp;
	LL lastValue;
	node(LL a=0,LL b=0):
		dp(a),lastValue(b){}
	bool operator < (const node &nd)const
	{
		return dp<nd.dp;
	}
};

set <node> st;
LL a[maxn],dp[maxn];

void process(LL dp,LL lv)   
{
	/*
	更新set
	若lv比 lv_2 大 ,要插入set的条件是dp>dp_2
	若lv比lv_2小,且dp>dp_2那么set里面的有些节点要被删掉 
	*/
	if(st.empty())
	{
		st.insert(node(dp,lv));
		return ;
	}
	node newnode=node(dp,lv); 
	typedef set <node>::iterator itor;
	itor it = st.lower_bound(newnode);
	if(it==st.end())
	{
		itor temp = it;
		itor per = --temp;
		while(per!=st.begin() && per->lastValue>=lv)
			st.erase(per--);
		if(per==st.begin() && per->lastValue>=lv)
			st.erase(per);
		st.insert(newnode);
	}
	else
	{
		if(it==st.begin())
		{
			if(it->dp==dp)
			{
				if(it->lastValue<=lv)
					return ;
				
				st.erase(it);
				st.insert(newnode);
			}
			else
			{
				if(it->lastValue>lv)
				{
					st.insert(newnode);
				}
				else
				{
					return ;
				}
			}
		}
		else
		{
			if(it->lastValue<=lv)
				return ;
			itor per = it;
			if(it->dp!=dp)
				--per;
			while(per!=st.begin() && per->lastValue>=lv)
					st.erase(per--);
			if(per==st.begin() && per->lastValue>=lv)
				st.erase(per);
			st.insert(newnode);
		}
	}
}
LL Find(LL x)
{
	typedef set <node>::iterator itor;
	LL down=0,mid,up=INF;
	LL ret(0);
	while(down<=up)
	{
		mid=(down+up)/2;
	//	printf("mid:%lld\n",mid);
		itor it = st.lower_bound(node(mid));
		if(it!=st.end() && it->lastValue<x)
		{
			down = mid + 1;
			if(it->dp>ret)
				ret=it->dp;
		}
		else
		{
			up= mid -1;
		}
	}
	return ret;
}

int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		int r,h;
		scanf("%d%d",&r,&h);
		a[i]=r*1ll*r*h;
	}
	LL ans(0);
	for(int i=1;i<=n;i++)
	{
		LL f=Find(a[i])+a[i];
		ans=max(ans,f);
		process(f,a[i]);	
	}
	printf("%.10lf",ans*1.0*acos(-1));
	return 0;
}



解法二

分析:将体积离散化之后,作为线段树的节点编号,每个节点存区间的最大体积和就ok了,容易理解,代码又好敲。

代码:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 1ll<<62;
const LL MINT = ~0u>>1;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

const int maxn = 2e5;
LL a[maxn],uniq[maxn];       //体积 
LL tree[maxn<<2];   //线段树维护体积和 

void update(int pos,LL v,int l,int r,int rt)
{
	if(l==r)
	{
		tree[rt]=max(tree[rt],v);
		return ;
	}
	int m=(l+r)>>1;
	if(pos<=m)
		update(pos,v,lson);
	else
		update(pos,v,rson);
	tree[rt]=max(tree[rt<<1],tree[rt<<1|1]);
}
LL query(int L,int R,int l,int r,int rt)
{
	if(L<=l && r<=R)
		return tree[rt];
	int m=(l+r)>>1;
	LL ret(-INF);
	if(L<=m)
		ret=max(ret,query(L,R,lson));
	if(R>m)
		ret=max(ret,query(L,R,rson));
	return ret;
}

int Find(LL f,int n)
{
	int down=1,mid,up=n;
	while(down<=up)
	{
		mid = (down+up)>>1;
		if(uniq[mid]==f)	return mid;
		if(uniq[mid]>f)	up=mid-1;
		else	down=mid+1;
	}
	return -1;
}

int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		int r,h;
		scanf("%d%d",&r,&h);
		uniq[i]=a[i]=r*1ll*r*h;
	}
	sort(uniq+1,uniq+1+n);
	int tail=unique(uniq+1,uniq+n+1)-uniq-1;
	LL ans(0);
	for(int i=1;i<=n;i++)
	{
		int index=Find(a[i],tail);
		LL sum(a[i]);
		if(index>1)
			sum+=query(1,index-1,1,n,1);
		ans=max(ans,sum);
		update(index,sum,1,n,1); 
	}
	printf("%.10lf\n",ans*acos(-1));
	return 0;
}







内容概要:本文提出了一种基于非合作博弈理论的居民负荷分层调度模型,并结合双层鲸鱼优化算法(Two-level Whale Optimization Algorithm)进行高效求解,模型与算法均通过Matlab代码实现。研究针对电力系统中居民侧用电负荷的复杂调度问题,引入非合作博弈机制刻画各用户之间的利益竞争关系,实现负荷的分层优化分配;同时设计双层优化架构,上层优化资源配置,下层模拟用户自主决策行为,提升了模型的实用性与合理性。通过智能优化算法求解多层级、非凸非线性的博弈模型,有效提高了调度方案的收敛性与全局寻优能力,适用于现代智能电网中的需求侧管理与能源优化场景。; 适合人群:具备电力系统基础理论知识和Matlab编程能力,从事智能电网、能源优化调度、需求侧管理、博弈论应用等方向的科研人员、高校研究生及工程技术人员。; 使用场景及目标:①应用于居民区电力负荷的分层优化调度系统设计与仿真分析;②为非合作博弈在多主体能源系统建模中的应用提供方法论支持;③利用双层鲸鱼算法解决具有嵌套结构的复杂双层优化问题,提升求解效率与调度方案的可行性。; 阅读建议:建议读者结合提供的Matlab代码深入理解模型构建逻辑与算法实现流程,重点关注博弈模型的效用函数设计、纳什均衡求解思路以及双层优化结构的迭代机制,宜配合实际用电数据开展复现实验以验证模型有效性与鲁棒性。
内容概要:本文围绕基于自适应神经模糊推理系统(ANFIS)智能控制器的可再生能源微电网功率管理系统展开研究,结合Simulink仿真实现,深入探讨了微电网中功率的智能调控与经济机组组合调度问题。通过引入ANFIS控制器,有效应对风能、光伏等可再生能源出力的波动性与不确定性,提升系统运行的稳定性与电能质量。研究内容涵盖微电网多源协调控制策略、功率平衡管理、优化调度模型构建及仿真验证,实现了对分布式电源、储能系统和负荷的协同优化,兼顾经济性与可靠性目标,并通过仿真平台验证了所提方法的有效性与优越性。; 适合人群:具备电力系统、自动化或新能源相关专业背景,熟悉Matlab/Simulink仿真环境,从事微电网能量管理、智能控制、能源优化等领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①用于高比例可再生能源接入场景下的微电网能量管理系统研发与教学实践;②为实现微电网功率稳定控制与经济高效运行提供先进的智能控制解决方案;③支撑高水平学术论文复现、科研课题攻关及实际工程项目的仿真验证与方案优化。; 阅读建议:建议结合提供的Simulink模型与相关代码进行动手实践,重点关注ANFIS控制器的设计流程、规则库构建与参数调优方法,并通过与传统PID或MPC控制策略的对比实验,深入理解其在动态响应与鲁棒性方面的优势。同时可进一步拓展文中提出的优化调度逻辑,应用于多目标、多约束的复杂实际应用场景中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值