首页 > 其他分享 >dp学习笔记

dp学习笔记

时间:2023-02-17 10:55:41浏览次数:39  
标签:int j1 笔记 学习 -- num dp qwq

目录

斜率优化dp

H.仓库建设

思路

很容易想暴力,因为只能往后送物资,从后往前计算dp[i]为在i这里建造仓库且i~n都有地可去的最小价值
为了方便计算,我把x[i]修改为到n节点的距离,用f维护p[i]*x[i]的后缀和,num维护p[i]后缀和
那么方程为

\[dp[i]=min(dp[j]+(f[i+1]+c[i])+(-x[j]*num[i+1])+(x[j]*num[j]-f[j])) \]

推式子得,若j1<j2且j1优于j2,必然满足

\[num[i+1]\ge\tfrac{Y(j2)-Y(j1)}{X(j2)-X(j1)} \]

其中$$ Y(j)=dp[j]+x[j]*num[j]-f[j]$$

\[X(j)=x[j] \]

代码

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define N 1000005
#define ll long long
inline int read(){
	int x=0,f=1; char c=getchar();
	while(c>'9'||c<'0'){if(c=='-') f=-1; c=getchar();}
	while(c<='9'&&c>='0'){x=(x<<3)+(x<<1)+(c^'0'); c=getchar();}
	return x*f;
}int n;
ll dp[N],x[N],p[N],c[N];
ll inf=99999999999999;
ll f[N],num[N];
int tmp[N];
ll Y(int w1){
	return dp[w1]+x[w1]*num[w1]-f[w1];
}ll X(int w1){
	return x[w1];
}
double s(int w1,int w2){
	if(X(w2)==X(w1)) return inf;
	return 1.0*(1.0*(Y(w2)-Y(w1))/(X(w2)-X(w1)*1.0));
}
int main(){
//	freopen("1.txt","r",stdin);
	n=read();
	for(int i=0;i<=n;i++) dp[i]=inf;
	for(int i=1;i<=n;i++){
		x[i]=read(),p[i]=read(),c[i]=read();
	}//while(!p[n]) n--;
	int lmy=x[n];
	for(int i=1;i<=n;i++) x[i]=lmy-x[i];
	for(int i=n;i>=1;i--){
	    f[i]=f[i+1]+p[i]*x[i];
		num[i]=num[i+1]+p[i]; 
	//	cout<<f[i]<<" "<<num[i]<<endl;
	}
	int h=1,t=0;
	tmp[++t]=n;
	dp[n]=c[n];
	for(int i=n-1;i>=0;i--){
		while(h<t&&(s(tmp[h],tmp[h+1])<=num[i+1])) 	h++;
		int j=tmp[h];
		dp[i]=min(dp[i],(dp[j]+(f[i+1]-f[j])-x[j]*(num[i+1]-num[j])+c[i]));
		while(h<t&&(s(tmp[t-1],tmp[t])>=s(tmp[t],i))) t--;
		tmp[++t]=i;
	}printf("%lld\n",dp[0]);
	return 0;
}

J.土地购买

思路:

排序后处理掉没用的块,然后就能保证l单调减,r单调增,此时保证所选择的块一定呆在一起,可以用假设法证明,如果最优解不相邻,那么中间的不优,矛盾,得证
然后可以列出方程:

\[dp[i]=min(dp[j]+qwq[j+1].l*qwq[i].r) \]

假设\(j1<j2\)并且\(j2优于j1\),此时可以将\(j1\)从队首弹出,必然满足

\[qwq[i].r\ge\tfrac{dp[j2]-dp[j1]}{qwq[j1].l-qwq[j2].l} \]

代码

点击查看代码
	sort(s+1,s+n+1,cmp);
	ll max_r=0;
	for(int i=1;i<=n;i++){
		if(max_r>=s[i].r) 	continue;
		max_r=max(max_r,s[i].r);
		qwq[++q]=s[i];
	}
	int t=1,h=1;
	for(int i=1;i<=q;i++){
		while(h<t&&ss(tmp[h],tmp[h+1])<=qwq[i].r)
			h++;
		int j=tmp[h];
		dp[i]=min(dp[i],dp[j]+qwq[j+1].l*qwq[i].r);
		while(h<t&&ss(tmp[t-1],tmp[t])>=ss(tmp[t],i)) t--;
		tmp[++t]=i;
	} 
	printf("%lld\n",dp[q]);

标签:int,j1,笔记,学习,--,num,dp,qwq
From: https://www.cnblogs.com/limingyun/p/17129364.html

相关文章

  • python爬虫基本学习——函数(2.16博客补)
    函数概念:编写程序时,需要某块代码多次,为了提高编写效率和代码的重用,把具有独立功能的代码块组织为一个小模块,即函数。代码练习'''#函数的定义defprintinfo():pri......
  • 机器学习-集成学习GBDT
    目录前言一、原理二、优缺点三、实际应用四、常见的GBDT变体五、代码六、总结前言​ GBDT(GradientBoostingDecisionTrees)是一种基于决策树的集成学习算法,它通过逐步......
  • 《分布式技术原理与算法解析》学习笔记Day14
    分布式计算模式:Stream什么是流数据?实时性任务主要是针对流数据处理,对处理时延要求很高,通常需要常驻服务进程,等待数据的随时到来随时处理,以保证低时延。流数据有4个特征:......
  • 读Java实战(第二版)笔记12_重构、测试和调试
    1. 设计模式1.1. 对设计经验的归纳总结1.2. 一种可重用的蓝图1.3. Java5引入了for-each循环1.3.1. 替代了很多显式使用迭代器的情形1.4. Java7推出的菱形操......
  • 安装Linux操作系统,学习Linux基础(必做)
    掌握了Linux命令的学习方法https://www.cnblogs.com/bky20221301/p/16652478.html......
  • 数据结构个人学习推荐
    目录学好这门课的重要性学习方法多看图例并动笔画图步步为营且不断重复Showmeyourcode!尝试输出所学知识常见的问题C都还给老师了,还需要返工吗?需不需要先学某门语言再......
  • 谷粒学院day03笔记
    前端开发一、工具vscode层级:文件夹->工作区->文件/文件夹插件:二、ECMAScript6简介1.ECMAScript和JavaScript的关系2.ES6与ECMAScript2015的关系3.......
  • markdown学习
    markdown使用学习#+标题名字选择标题最多6级一个#表示加一级一级最大字体对字体加粗等操作hello**hello**粗体hello*hello*斜体hello***hello*......
  • agc061_c 容斥+dp
    题意有两个长度为\(n\)的严格递增序列\(A_i,B_i\),满足\(\foralli\len,A_i<B_i\),且\(A_i\)和\(B_i\)的所有元素恰好取遍\(1-2n\)。现在有一个队列,对于\(1\)......
  • 2.16 背包学习
    11.背包问题求方案数思路求最优方案数可以分成两步第一步求出最优方案,也就是最大价值第二部求最大价值下的方案数具体有多少种而求出当前i,j下最大价值,然后求出相应......