HDU3480:Division——题解
http://acm.hdu.edu.cn/showproblem.php?pid=3480
将一列数划分成几个集合,这些集合的并集为该数列,求每个数列的(最大值-最小值)^2的和的最小值。
简单的dp都会写,就不讲了。
然后就是四边形优化了,参考:https://blog.csdn.net/noiau/article/details/72514812
事实上四边形优化的条件一般是靠打表打出来的。
于是简单记录下吧:
先排序。
设dp[i][j]为前j个数划分成i个集合的最小值,cost[i][j]为i~j的集合价值。
显然有dp[i][j]=min{dp[i][j],dp[i][k]+cost[k+1][j]}
接着打表得出(就是打一个矩阵,观察矩阵每行每列都是递增的):
s[i-1][j]<=s[i][j]<=s[i][j+1]
然后就可以利用第三条结论来优化了。
(此外能否用四边形不等式优化还和你如何定义dp也是有关系的……我就是被坑了把dp两个状态倒换一下才行。)
还有一些注意事项看一下https://www.cnblogs.com/mlystdcall/p/6525962.html吧。
#include<cstdio>
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int N=;
const int M=;
const int INF=1e9;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
inline int sqr(int k){return k*k;}
int a[N],dp[M][N],s[M][N];
int main(){
int t=read();
for(int cas=;cas<=t;cas++){
printf("Case %d: ",cas);
int n=read(),m=read();
for(int i=;i<=n;i++)a[i]=read();
sort(a+,a+n+);
for(int i=;i<=n;i++){
dp[][i]=sqr(a[i]-a[]);
s[][i]=;
}
for(int i=;i<=m;i++){
s[i][n+]=n-;
for(int j=n;j>=i;j--){
dp[i][j]=INF;
for(int k=s[i-][j];k<=s[i][j+];k++){
if(dp[i][j]>dp[i-][k]+sqr(a[j]-a[k+])){
dp[i][j]=dp[i-][k]+sqr(a[j]-a[k+]);
s[i][j]=k;
}
}
}
}
printf("%d\n",dp[m][n]);
}
return ;
}
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
HDU3480:Division——题解的更多相关文章
- HDU3480 Division —— 斜率优化DP
题目链接:https://vjudge.net/problem/HDU-3480 Division Time Limit: 10000/5000 MS (Java/Others) Memory ...
- hdu3480 Division(dp平行四边形优化)
题意:将n个数分成m段,每段的代价为最大值减最小值的平方,为代价最小是多少n<=10000 ,m<=5000 题解:先拍好序,从小到大,这样绝对是花费最小的,不过怎么样来做呢?一定很容易想 ...
- HDU-3480 Division (四边形不等式优化DP)
题目大意:将n个数分成m组,将每组的最大值与最小值的平方差加起来,求最小和. 题目分析:先对数排序.定义状态dp(i,j)表示前 j 个数分成 i 组得到的最小和,则状态转移方程为dp(i,j)=mi ...
- [HDU3480] Division [四边形不等式dp]
题面: 传送门 思路: 因为集合可以无序选择,所以我们先把输入数据排个序 然后发先可以动归一波 设$dp\left[i\right]\left[j\right]$表示前j个数中分了i个集合,$w\le ...
- HDU3480 Division——四边形不等式或斜率优化
题目大意 将N个数分成M部分,使每部分的最大值与最小值平方差的和最小. 思路 首先肯定要将数列排序,每部分一定是取连续的一段,于是就有了方程 $\Large f(i,j)=min(f(i-1,k-1) ...
- CF1444A (1445C)Division 题解
题意:求最大的正整数 \(x\) ,使 \(x \mid p且q \nmid x\) . 首先,当 \(q \nmid p\) ,显然取 \(x=p\) 是最优解. 现在,我们考虑 \(q \mid ...
- hdu3480 Division
Problem Description Little D is really interested in the theorem of sets recently. There's a problem ...
- [Leetcode Week3]Evaluate Division
Evaluate Division题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/evaluate-division/description/ Desc ...
- HDU2829 Lawrence —— 斜率优化DP
题目链接:https://vjudge.net/problem/HDU-2829 Lawrence Time Limit: 2000/1000 MS (Java/Others) Memory L ...
随机推荐
- android学习七 菜单
1.菜单分类 常规菜单 子菜单 上下文菜单 图标菜单 辅助菜单 交替菜单 2.菜单类 andriod.view.menu 3.菜单的参数 名称:字符串标题 菜单ID:整数 ...
- mysql中的直方图采样逻辑
int handler::sample_next(uchar *buf) { // Temporary set inited to RND, since we are calling rnd_next ...
- 使用Iview Menu 导航菜单(非 template/render 模式)
1.首先直接参照官网Demo例子,将代码拷贝进项目中运行, 直接报错: Cannot read property 'mode' of undefined. 然后查看官网介绍,有一行注意文字,好吧. 2 ...
- 剑指offer-顺时针打印矩阵19
题目描述 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数 ...
- 十面阿里,七面头条,六个Offer,春招结束
作者:jkgeekjack链接:https://www.nowcoder.com/discuss/80156?type=0&order=0&pos=13&page=2来源:牛客 ...
- POJ 1269 Intersecting Lines(直线求交点)
Description We all know that a pair of distinct points on a plane defines a line and that a pair of ...
- Alphabetic Removals(模拟水题)
You are given a string ss consisting of nn lowercase Latin letters. Polycarp wants to remove exactly ...
- Python练习—循环
1.输入n的值,求出n的阶乘. s=1 n = int(input("请输入一个数")) for i in range(1,n+1): s=s*i print(s) 2.折纸上月球 ...
- TensorFlow高级API(tf.contrib.learn)及可视化工具TensorBoard的使用
一.TensorFlow高层次机器学习API (tf.contrib.learn) 1.tf.contrib.learn.datasets.base.load_csv_with_header 加载cs ...
- 福大软工1816 · 第五次作业 - 结对作业2_map与unordered map的比较测试
测试代码: #include <iostream> using namespace std; #include <string> #include <windows.h& ...