2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 D Merchandise (斜率优化)
Description:
The elderly aunts always like to look for bargains and preferential merchandise. Now there is a shop carrying out group purchase promotion.
Rules are as follows :
There are r pieces of promotional items, and each item is only one. In the group purchase, everyone will buy one at least and have to conform the rules if they want to enjoy the benefit :
All the merchandise at a prime number has to be purchased ;
the merchandise at non-prime number cannot be chosen ;
The amount of money that each person pays is the square of the difference between the maximum and minimum value of the product he or she chooses. Notice that there may be several merchandises having the same price.
(If a person buys only one item, follow the rules and spend ¥ 0.00)
Assume that there are m people in a group, and everyone should enjoy the benefit. Please arrange each person's choice of merchandise reasonably, so that the sum of money paid by m people can be the minimum.
The number of merchandise with a price of prime is n,m<=n , n<=5000
Input:
The input contains multiple test cases.
In the first line of the input there’s an integer T which is the number of test cases. Then the description of T test cases will be given.
For any test case, the first line of input consists of two separated integers r and m.
(0<r<=100000,0<m<=1000)
The second line should consists of r space separated integers k1,k2...kr.
(1<ki<2^16,1<=i<=r)
ki represents the price of one item
Output:
Print one integer sum (sum<2^32)——the minimum number of money paid by m people.
忽略每行输出的末尾多余空格
样例输入
1
6 2
5 6 10 2 11 3
样例输出
9 题意:给你r个数,首先你要跳出其中的所有的素数(n<=5000),然后将这些素数分成m(<=n)个组。
每个组的权值为(这个组中最大元素-这个组最小元素)^2,问各组的权值的和最小为多少
思路:
首先我们想到先排序然后dp
先写转移方程,我们设dp[i][j]为前i个数分为j个集合的权值的和,则有
还有j那维需要循环,这个复杂度为n^3,显然是超时的。我们利用斜率优化算法优化成n^2的
将上面等式右边{}内的看成关于自变量k的一个函数val(k)
将k1带入得到
将k看成变量,分离变量与常量整理上式。
这个式子就像一个直线的方程,我们的目的是让dp[i][j]最小即截距dp[i][j]+a[i]^2最小
这个直线的斜率是2*a[i],也就是说坐标轴上有好多点,每个具体的k都确定一个点(a[k],dp[k-1][j-1]+a[k]^2)
我们转化成了一个线性规划问题,假设当前有好几个点,我们只需要维护他们是下凸的就行了
即如果有三个连续的点k1,k2,k3,那么斜率(k2,k1)<斜率(k2,k3)
这个我们用单调队列维护。这样就能减少复杂度
代码如下:
#include <bits/stdc++.h> using namespace std;
typedef long long ll;
const ll inf = 1e18;
const int maxn = 5e5+;
const int maxm = ;
const int maxp = (<<)+;
bool check (int x){
for (int i=;i*i<=x;++i){
if (x%i==)
return false;
}
return true;
}
int prime[maxp];//保存素数
bool vis[maxp];
int r,n,m;
ll a[maxn],b[maxm];
ll dp[maxm][maxm];
int q[maxm];
int head,tail;
void getprime(int n)
{
int cnt = ;
memset(vis,,sizeof(vis));
for(int i=;i<n;i++)
{
if(!vis[i])
prime[cnt++]=i;
for(int j=;j<cnt&&i*prime[j]<n;j++)
{
vis[i*prime[j]]=;
if(i%prime[j]==)
break;
}
}
return ;
}
int main()
{
int t;
getprime(maxp);
//freopen("de.txt","r",stdin);
scanf("%d",&t);
dp[][]=;
for (int i=;i<maxm;++i)
dp[i][]=inf;
while (t--){
n = ;
ll x;
scanf("%d%d",&r,&m);
for (int i=;i<r;++i){
scanf("%lld",&x);
if (!vis[x]){
a[++n] = x;
}
}
sort(a+,a+n+);
for (int i=;i<=n;++i){
b[i] = a[i]*a[i];
}
for (int j=;j<=m;++j){
head = ,tail = ;
dp[][j]=inf;
for (int i=;i<=n;++i){
while (tail-head>=){
int x=q[tail-],y=q[tail-];
double v1,v2;
if (a[y]==a[x]) v1 = inf;
else v1=(dp[y-][j-]+b[y]-dp[x-][j-]-b[x])/(2.0*(a[y]-a[x]));
if (a[y]==a[i]) v2 = inf;
else v2=(dp[i-][j-]+b[i]-dp[y-][j-]-b[y])/(2.0*(a[i]-a[y]));
if (v1>v2)
tail--;
else
break;
}
q[tail++] = i;
while (tail-head>=){
int x=q[head],y=q[head+];
double v1;
if (a[y]==a[x]) v1 = inf;
else v1=(dp[y-][j-]+b[y]-dp[x-][j-]-b[x])/(2.0*(a[y]-a[x]));
if (v1<a[i])
head++;
else
break;
}
int tmp = q[head];
dp[i][j] = dp[tmp-][j-]+(ll)(a[i]-a[tmp])*(ll)(a[i]-a[tmp]);
//printf("%lld %d %d\n",dp[i][j],i,j);
}
}
printf("%lld\n",dp[n][m]);
}
return ;
}
2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 D Merchandise (斜率优化)的更多相关文章
- 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 H题 Rock Paper Scissors Lizard Spock.(FFT字符串匹配)
2018 ACM-ICPC 中国大学生程序设计竞赛线上赛:https://www.jisuanke.com/contest/1227 题目链接:https://nanti.jisuanke.com/t ...
- 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 F题 Clever King(最小割)
2018 ACM-ICPC 中国大学生程序设计竞赛线上赛:https://www.jisuanke.com/contest/1227 题目链接:https://nanti.jisuanke.com/t ...
- 计蒜客 25985.Goldbach-米勒拉宾素数判定(大素数) (2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 B)
若干年之前的一道题,当时能写出来还是超级开心的,虽然是个板子题.一直忘记写博客,备忘一下. 米勒拉判大素数,关于米勒拉宾是个什么东西,传送门了解一下:biubiubiu~ B. Goldbach 题目 ...
- 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 I. Reversion Count (java大数)
Description: There is a positive integer X, X's reversion count is Y. For example, X=123, Y=321; X=1 ...
- 2017年中国大学生程序设计竞赛-中南地区赛暨第八届湘潭市大学生计算机程序设计大赛题解&源码(A.高斯消元,D,模拟,E,前缀和,F,LCS,H,Prim算法,I,胡搞,J,树状数组)
A------------------------------------------------------------------------------------ 题目链接:http://20 ...
- 第 46 届 ICPC 国际大学生程序设计竞赛亚洲区域赛(沈阳)
有时候,很简单的模板题,可能有人没有做出来,(特指 I ),到时候一定要把所有的题目全部看一遍 目录 B 题解 E F 题解 H I 题解&代码 J B 输入样例 3 2 1 2 1 2 3 ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 1001 - Buy and Resell 【优先队列维护最小堆+贪心】
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6438 Buy and Resell Time Limit: 2000/1000 MS (Java/O ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ's Salesman 【离散化+树状数组维护区间最大值】
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/O ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 1009 - Tree and Permutation 【dfs+树上两点距离和】
Tree and Permutation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Oth ...
随机推荐
- 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_01 File类_6_File类判断功能的方法
exists true表示路径是存在的 不存在的路径 不存在的路径返回false 相对路径的文件的判断 ‘ 不存在的相对路径 isDirectory和isFile 路径是不存在的 用这个方法之前最好先 ...
- cookie/http/https
今天再学习顺便外加复习下http的相关知识,顺便试试在笔记中导出一个长篇的图片回事怎么样的效果. HTTP相关知识,不是很全仅供参考
- Centos 下更改MySQL源数据存放目录(datadir)
MySQL在安装完成之后,其源数据默认存放在 /var/lib/mysql/ 目录下,一般情况下,该目录在根目录下,由于Linux系统默认 根目录所在挂载的磁盘容量有限,随着生产数据的不断产生,该目 ...
- github创建仓库,往github上上传自己的项目
k第一步: 在github上创建仓库 第二步: 创建一个新的项目,填写项目名称,描述 创建完成之后,跳转到下面的页面,下面红框中的网址要记住,在后面上传代码的时候需要使用 这个地址必须要记住!!! 第 ...
- JavaScript求两点之间相对于Y轴的顺时针旋转角度
需求: 已知一个向量,初始位置在y轴方向,如图红色箭头,绕中心点(x1, y1)旋转若干角度后,到达Line(x2,y2 x1,y1)的位置,求旋转角度 分析: 坐标点(x1, y1)(x2, y2) ...
- 《深入浅出WPF》学习总结之XAML标签语言二
x名称空间 “x名称空间”的这个X是映射XML名称空间时给他取的名字(如果用的是字母y,那他就叫“y名称空间了”),x名称空间里的成员(x.name.x.class)是专门给XAML编译器看的.用来引 ...
- Dijkstra经典算法注意点
Dijkstra经典算法注意点 前言 迪杰斯特拉算法,经典模板如下: void dij(int s) { for(int i=1; i<=n; i++) dis[i]=road[s][i]; v ...
- 浅谈格雷码(Grey Code)在信息学竞赛中的应用
1.格雷码的概念 1.性质 格雷码(Grey Code),又叫循环二进制码或反射二进制码,是一种编码方式,它的基本特点是任意两个相邻的格雷码只有一位二进制数不同. 常用的二进制数与格雷码间的转换关系如 ...
- Excel VBA批量处理寸照名字
需求:因为处理学生学籍照片,从照相馆拿回来的寸照是按班级整理好,文件名是相机编号的文件.那么处理的话,是这么一个思路,通过Excel表格打印出各班A4照片列表,让学生自行填上照片对应姓名.表格收回来后 ...
- kotlin和vertx和mongo写的一个服务器验证登陆功能(很简陋)
包结构长这个样子: server包:(服务器相关配置) HttpServer:用ver.x创建了一个http服务器,把接收到的req请求传入RPCRequest中: RPCRequest:解析请求bo ...