太空飞船(spaceship)

题目描述

21XX年,秋。

小诚是THU(Tomorrow Happy University)航天学院船舶设计系本科四年级的学生。为了顺利毕业,小诚仔细阅读了这几年被引用次数最多的十几篇会议论文,打算在权威理论的指导下设计一艘新型太空飞船。

这将是一艘环形的太空飞船,由N个舱室顺序组成。第i个舱室的设计长度为Li。为了给飞船提供能量,要在飞船上装置K个太空能量吸收器。

根据权威理论,这些吸收器应该尽量均匀地分散在飞船表面。也就是说,小诚要把飞船所有N个舱室划分成K个部分(每个部分包括连续一段舱室),并给每个部分配置一个能量吸收器。设第i个部分舱室的长度之和为si,则要令方差

∑i=1..K(si−s_avg)2∑i=1..K(si−s_avg)2

尽量小。其中s_avg 是K个部分的平均长度。

可是,这个问题对于已经大学四年级的小诚来说太难了。你能否帮助他完成设计呢?

为方便起见,输出方差最小值与K的平方的乘积。

输入

输入文件名为spaceship.in。

第一行,两个整数N,K。

第二行,N个整数L1, L2,⋯, LNL1, L2,⋯, LN,由空格隔开。依次表示每个舱室的长度。

输出

输出文件名为spaceship.out。

输出一行,为一个整数,表示方差最小值与K2K2的乘积。

样例输入

<span style="color:#333333"><span style="color:#333333">【样例输入1】
5 2
4 2 6 1 3
【样例输入2】
5 3
4 2 6 1 3</span></span>

样例输出

<span style="color:#333333"><span style="color:#333333">【样例输出1】
0
【样例输出2】
24</span></span>

提示

【样例解释】

第一组样例。要将飞船分为2段,最优划分方法为[2 6][1 3 4]。

第二组样例。要将飞船分为3段,最优划分方法为[4 2][6] [1 3]。

【数据规模与约定】

本题一共有10个测试点。

对于100%的数据,1≤Li≤1,0001≤Li≤1,000。

来源

BJOI2017一试


化简一下方差的式子,发现等价于要求最小。

k=2 双指针维护权值和1/2 的点

k=3 k=2的基础上二分

考虑n<=400的

令f[i][j] 表示前i个点分成j块的最小代价

f[i][j]=f[k][j-1]+(sum[i]-sum[k])^2

展开因为一维j之和上一维有关,滚掉

移过来

sum[i]递增,f[j]+sum[j]*sum[j] 递增

构处凸包就可以斜率优化了

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 600005
#define ll long long
using namespace std;
int n,k,l,r;
ll s[maxn],a[maxn],sum[maxn],f[405];
ll ans=1e18;
struct node{
ll x,y;
}q[405];
ll val(int a,int b){
return q[a].y-q[a].x*sum[b]*2;
}
node xl(node a,node b){
node c;c.x=b.x-a.x;c.y=b.y-a.y;
return c;
}
ll cr(node a,node b){
return a.x*b.y-a.y*b.x;
}
void tb(){
l=1;r=0;
for(int i=0;i<=n;i++){
node t=(node){sum[i],f[i]+sum[i]*sum[i]};
while(r>=2&&cr(xl(q[r-1],q[r]),xl(q[r-1],t))<0)r--;
q[++r]=t;
}
}
int main()
{
cin>>n>>k;
for(int i=1;i<=n;i++)scanf("%lld",&s[i]),s[i+n]=s[i];
for(int i=1;i<=2*n;++i)sum[i]=sum[i-1]+s[i];
if(n<=400){ for(int d=1;d<=n;d++){
ll t=s[1];for(int i=1;i<n;i++)s[i]=s[i+1];s[n]=t;
for(int i=1;i<=n;i++)sum[i]=sum[i-1]+s[i];
q[1].x=q[1].y=0;l=1,r=1;
for(int nn=1;nn<=k;nn++){
//cout<<nn<<endl;
for(int i=1;i<=n;i++){
while(l<r&&val(l,i)>val(l+1,i))l++;
f[i]=val(l,i)+sum[i]*sum[i];
//cout<<i<<' '<<f[i]<<' '<<l<<' '<<r<<endl;
}
tb();
} ans=min(ans,(ll)f[n]*k*k-(ll)(sum[n]*sum[n]*k));
}
cout<<ans<<endl;
return 0;
}
if(k==2){
int j=1;
for(int i=1;i<=n;i++){
while((sum[j+1]-sum[i-1])*2<=sum[n]&&j<=i+n-1)j++;
ll v1=sum[j]-sum[i-1],v2=sum[n]-v1;ans=min(ans,v1*v1+v2*v2);
v1=sum[j+1]-sum[i-1],v2=sum[n]-v1;ans=min(ans,v1*v1+v2*v2);
}
ans=k*(ans*k-(sum[n]*sum[n]));
cout<<ans<<endl;
} else {
int j=1;
for(int i=1;i<=n;i++){
while((sum[j+1]-sum[i-1])*3<=sum[n]&&j<=n+i-1)j++;
if(j>n+i-1)break;
l=j+1;r=n+i-1;// i-j j+1-l l+1-i+n-1
while(l<r){
int mid=l+r+1>>1;
if((sum[mid]-sum[j])*3>sum[n])r=mid-1;
else l=mid;
}
ll v1=sum[j]-sum[i-1],v2=sum[l]-sum[j],v3=sum[n]-v1-v2;ans=min(ans,v1*v1+v2*v2+v3*v3);
v1=sum[j]-sum[i-1],v2=sum[l-1]-sum[j],v3=sum[n]-v1-v2;ans=min(ans,v1*v1+v2*v2+v3*v3);
v1=sum[j]-sum[i-1],v2=sum[l+1]-sum[j];v3=sum[n]-v1-v2;ans=min(ans,v1*v1+v2*v2+v3*v3);
}
ans=k*(ans*k-(ll)(sum[n]*sum[n]));
cout<<ans<<endl;
}
return 0;
}

太空飞船(spaceship)的更多相关文章

  1. Unity3D--学习太空射击游戏制作(二)

    步骤三:创建主角 游戏的主角是一艘太空飞船,我们将使用一个飞船模型作为游戏的主角,并赋予他一个脚本,控制他的运动,游戏体的组件必须依赖于脚本才能运行. 01:在Project窗口找到Player.fb ...

  2. php7新增的两个操作符---null合并及飞船操作符

    <?php //null合并操作符?? //(太空)飞船操作符<=> //The operator returns 0 if both operands are equal, 1 i ...

  3. [Effective JavaScript 笔记]第38条:在子类的构造函数中调用父类的构造函数

    示例 场景类 场景图(scene)是在可视化的过程中(如游戏或图形仿真场景)描述一个场景的对象集合.一个简单的场景包含了在该场景中的所有对象(称角色),以及所有角色的预加载图像数据集,还包含一个底层图 ...

  4. Sprite Kit编程指南(1)-深入Sprite Kit

    深入Sprite Kit 学习Sprite Kit最好的方法是在实践中观察它.此示例创建一对场景和各自的动画内容.通过这个例子,你将学习使用Sprite Kit内容的一些基础技术,包括: ·      ...

  5. POJ 3041 Asteroids / UESTC 253 Asteroids(二分图最大匹配,最小点匹配)

    POJ 3041 Asteroids / UESTC 253 Asteroids(二分图最大匹配,最小点匹配) Description Bessie wants to navigate her spa ...

  6. 重新精读《Java 编程思想》系列之组合与继承

    Java 复用代码的两种方式组合与继承. 组合 组合只需将对象引用置于新类中即可. 比如我们有一个B类,它具有一个say方法,我们在A类中使用B类的方法,就是组合. public class B { ...

  7. Golang+Protobuf+PixieJS 开发 Web 多人在线射击游戏(原创翻译)

    简介 Superstellar 是一款开源的多人 Web 太空游戏,非常适合入门 Golang 游戏服务器开发. 规则很简单:摧毁移动的物体,不要被其他玩家和小行星杀死.你拥有两种资源 - 生命值(h ...

  8. [Unity3D]Unity资料大全免费分享

     都是网上找的连七八糟的资料了,整理好分享的,有学习资料,视频,源码,插件……等等 东西比较多,不是所有的都是你需要的,可以按  ctrl+F 来搜索你要的东西,如果有广告,不用理会,关掉就可以了,如 ...

  9. Unity3D插件分享

    网上看到一个讲unity3D插件的,看着不错,转载过来. 本文汇总了近百个Unity3D插件,供大家参考下载. 2D_Toolkit_1.51 动画开发插件包 FingerGestures 触摸插件 ...

随机推荐

  1. centos6 下查看SELinux状态 关闭SELinux

    转载自:https://blog.csdn.net/boomjane_testingblog/article/details/52859977 SELinux(Security-Enhanced Li ...

  2. 基于mybatis设计简单OA系统问题3

    1.  问题:使用mybatis更新数据失败 描述:java.lang.NullPointerException 提交表单 com.duma.entity.User.updateUser - ==&g ...

  3. python__基础 : 类的__new__方法与实现一个单例

    __new__ : 这个方法的作用主要是创建一个实例,在创建实例时首先会调用 __new__方法 ,然后调用__init__对实例进行初始化, 如果想修改 __new__ 这个方法,那么最后要 ret ...

  4. php-5.6.26源代码 - PHP文件汇编成opcode(require、include的差异)

    文件 php-5.6.26/Zend/zend_language_scanner.c ZEND_API zend_op_array *compile_file(zend_file_handle *fi ...

  5. Python学习之函数参数

    上一节,我们学习了Python中是如何定义和调用函数且如何得到返回值的.在调用函数时,有的函数需要参数来启动函数,有的则无需参数.这一节我们来介绍Python中有哪些参数类型. 位置参数 在调用函数时 ...

  6. Idea搭建spring framework源码环境

    spring的源码目前放在github上,https://github.com/spring-projects/spring-framework 一.安装Git 二.安装Gradle gradle为解 ...

  7. PHP.13-日历类实现

    日历类实现 1.输出星期 calendar.class.php <?php class Calendar{ function out(){//输出表格 echo '<table align ...

  8. HTTPClient和HttpURLConnection实例对比

    HttpURLConnection是java的标准类,什么都没封装. HTTPClient是个开源框架,封装了访问http的请求头,参数,内容体,响应等等. 简单来说,HTTPClient就是一个增强 ...

  9. laravel5.5服务提供器

    目录 1. 编写服务提供器 1.1 注册方法 register 1.1.1 简单绑定 1.1.2 绑定单例 1.1.3 绑定实例 1.1.4 绑定初始数据 1.2 引导方法 boot 2. 注册服务提 ...

  10. 编译器错误消息: CS1617: 选项“6”对 /langversion 无效

    编译错误 说明: 在编译向该请求提供服务所需资源的过程中出现错误.请检查下列特定错误详细信息并适当地修改源代码. 编译器错误消息: CS1617: 选项“6”对 /langversion 无效:必须是 ...