【斜率/四边形不等式DP】【hdu 2829】Lawrence

http://acm.hdu.edu.cn/showproblem.php?pid=2829


给你一个序列A,请你把序列A分成连续K个子段,每个子段的代价是 sum(A[i]*A[j]) 其中 i < j。请问如何分组使代价最小。
    数据范围|A|,K <1000

这道题用四边形和斜率都可以


四边形很简单,不多说,直接套(chao)模板

//#define _TEST _TEST
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
/************************************************
Code By willinglive    Blog:http://willinglive.cf
************************************************/
#define rep(i,l,r) for(int i=l,___t=(r);i<=___t;i++)
#define per(i,r,l) for(int i=r,___t=(l);i>=___t;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define LL long long
#define INE(i,u,e) for(int i=head[u];~i;i=e[i].next)
inline const int getint()
{
    int r=0,k=1;char c=getchar();
    for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
    for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';
    return k*r;
}
/
int n,m;
int a[1010],sum[1010];
LL dp[1010][1010],s[1010][1010],cost[1010][1010];
/
/
void input()
{
	m++;
    rep(i,1,n) a[i]=getint(),sum[i]=sum[i-1]+a[i];
}
void solve()
{
	MS(dp,0x3f);
	rep(i,1,n) rep(j,i,n) cost[i][j]=cost[i][j-1]+(sum[j-1]-sum[i-1])*a[j];
	rep(i,0,m) dp[0][i]=0;
	rep(i,1,n) dp[i][1]=cost[1][i],s[i][1]=0;
	rep(j,1,m)
	{
		s[n+1][j]=n;
		per(i,n,j)
		{
			rep(k,s[i][j-1],s[i+1][j])
			{
				if(dp[i][j]>dp[k][j-1]+cost[k+1][i])
				{
					s[i][j]=k;
					dp[i][j]=dp[k][j-1]+cost[k+1][i];
				}
			}
		}
	}
    LL ans=(((unsigned long long)0)-1)>>1;
    rep(i,1,m) ans=min(ans,dp[n][i]);
    cout<<ans<<endl;
}
/
int main()
{
    #ifndef _TEST
    freopen("std.in","r",stdin); freopen("1.out","w",stdout);
    #endif
    while(scanf("%d%d",&n,&m),n+m)
    {
    input();
    solve();
    }
    return 0;
}

斜率,我的草稿:

dp[i][j]=min{dp[k][j-1]+cost[k+1][i]}


sum[i][j]^2=(a[i]+...+a[j])^2=sum2[i][j]+2cost[i][j]
cost[i][j]=(sum[i][j]^2-sum2[i][j])/2


dp[i][j]=min{dp[k][j-1]+(sum[k+1][i]^2-sum2[k+1][i])/2}
dp[i][j]=min{dp[k][j-1]+(s[i]^2-2*s[i]*s[k]+s[k]^2-s2[i]+s2[k])/2}
x<y,x比y优
dp[x][j-1]+(s[i]^2-2*s[i]*s[x]+s[x]^2-s2[i]+s2[x])/2<dp[y][j-1]+(s[i]^2-2*s[i]*s[y]+s[y]^2-s2[i]+s2[y])/2
dp[x][j-1]+(-2*s[i]*s[x]+s[x]^2+s2[x])/2<dp[y][j-1]+(-2*s[i]*s[y]+s[y]^2+s2[y])/2
dp[x][j-1]-s[i]*s[x]+s[x]^2/2+s2[x]/2<dp[y][j-1]-s[i]*s[y]+s[y]^2/2+s2[y]/2
s[i]<(dp[y][j-1]+s[y]^2/2+s2[y]/2-dp[x][j-1]-s[x]^2/2-s2[x]/2)/(s[y]-s[x])
s[i]<(dp[y][j-1]+s[y]^2/2+s2[y]/2) - dp[x][j-1]+s[x]^2/2+s2[x]/2)) / (s[y] - s[x])
Y[k]=dp[k][j-1]+s[k]^2/2+s2[k]/2
X[k]=s[k]
s[i]<(Y[y]-Y[x]) / (X[y]-X[x])

满足条件小的优


斜率还有一种方法:http://hi.baidu.com/adrnpduvzbjnpsr/item/0af88fb33b03a3fb62388eda

基本思想也是转化为前缀和

//#define _TEST _TEST
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
/************************************************
Code By willinglive    Blog:http://willinglive.cf
************************************************/
#define rep(i,l,r) for(int i=l,___t=(r);i<=___t;i++)
#define per(i,r,l) for(int i=r,___t=(l);i>=___t;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define LL long long
#define INE(i,u,e) for(int i=head[u];~i;i=e[i].next)
inline const int getint()
{
    int r=0,k=1;char c=getchar();
    for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
    for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';
    return k*r;
}
/
int n,m;
int a[1001];
LL s[1001],s2[1001];
LL dp[1001][1001];
int q[1010],l,r,j;
/
inline LL sqr(LL x){return x*x;}
LL X(int k){return s[k];}
LL Y(int k){return dp[k][j-1]+(sqr(s[k])+s2[k])/2;}
double slope(int k,int j){return (double)(Y(k)-Y(j))/(X(k)-X(j));}
/
void input()
{
	m++;
    rep(i,1,n) a[i]=getint(),s[i]=s[i-1]+a[i],s2[i]=s2[i-1]+sqr(a[i]);
}
void solve()
{
	rep(i,1,n) dp[i][1]=(sqr(s[i])-s2[i])/2;
    for(j=2;j<=m;j++)
    {
    	l=r=0;
    	rep(i,1,n)
    	{
    		while(l<r&&slope(q[l],q[l+1])<s[i])l++;
    		int k=q[l]; dp[i][j]=dp[k][j-1]+(sqr(s[i]-s[k])-(s2[i]-s2[k]))/2;
    		while(l<r&&slope(q[r],q[r-1])>slope(i,q[r]))r--;
    		q[++r]=i;
    	}
    }
    cout<<dp[n][m]<<endl;
}
/
int main()
{
    #ifndef _TEST
    freopen("std.in","r",stdin); freopen("2.out","w",stdout);
    #endif
    while(scanf("%d%d",&n,&m),n+m)
    {
    input();
    solve();
    }
    return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
基于C++和LUA的服务端游戏引擎框架,也可以用于其它服务端系统。 C++是一种广泛使用的编程语言,它是由Bjarne Stroustrup于1979年在新泽西州美利山贝尔实验室开始设计开发的。C++是C语言的扩展,旨在提供更强大的编程能力,包括面向对象编程和泛型编程的支持。C++支持数据封装、继承和多态等面向对象编程的特性和泛型编程的模板,以及丰富的标准库,提供了大量的数据结构和算法,极大地提高了开发效率。12 C++是一种静态类型的、编译式的、通用的、大小写敏感的编程语言,它综合了高级语言和低级语言的特点。C++的语法与C语言非常相似,但增加了许多面向对象编程的特性,如类、对象、封装、继承和多态等。这使得C++既保持了C语言的低级特性,如直接访问硬件的能力,又提供了高级语言的特性,如数据封装和代码重用。13 C++的应用领域非常广泛,包括但不限于教育、系统开发、游戏开发、嵌入式系统、工业和商业应用、科研和高性能计算等领域。在教育领域,C++因其结构化和面向对象的特性,常被选为计算机科学和工程专业的入门编程语言。在系统开发领域,C++因其高效性和灵活性,经常被作为开发语言。游戏开发领域中,C++由于其高效性和广泛应用,在开发高性能游戏和游戏引擎中扮演着重要角色。在嵌入式系统领域,C++的高效和灵活性使其成为理想选择。此外,C++还广泛应用于桌面应用、Web浏览器、操作系统、编译器、媒体应用程序、数据库引擎、医疗工程和机器人等领域。16 学习C++的关键是理解其核心概念和编程风格,而不是过于深入技术细节。C++支持多种编程风格,每种风格都能有效地保证运行时间效率和空间效率。因此,无论是初学者还是经验丰富的程序员,都可以通过C++来设计和实现新系统或维护旧系统。3
该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值