HDU 3480 Division(斜率优化+二维DP)
2016-01-10 21:24
423 查看
Division
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 999999/400000 K (Java/Others)Total Submission(s): 3984 Accepted Submission(s): 1527
[align=left]Problem Description[/align]
Little D is really interested in the theorem of sets recently. There’s a problem that confused him a long time.
Let
T be a set of integers. Let the MIN be the minimum integer in T and MAX
be the maximum, then the cost of set T if defined as (MAX – MIN)^2. Now
given an integer set S, we want to find out M subsets S1, S2, …, SM of
S, such that
and the total cost of each subset is minimal.
[align=left]Input[/align]
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 contains two integers N (≤ 10,000) and M
(≤ 5,000). N is the number of elements in S (may be duplicated). M is
the number of subsets that we want to get. In the next line, there will
be N integers giving set S.
[align=left]Output[/align]
For
each test case, output one line containing exactly one integer, the
minimal total cost. Take a look at the sample output for format.
[align=left]Sample Input[/align]
2
3 2
1 2 4
4 2
4 7 10 1
[align=left]Sample Output[/align]
Case 1: 1
Case 2: 18
Hint
The answer will fit into a 32-bit signed integer.
[align=left]Source[/align]
2010 ACM-ICPC Multi-University Training Contest(5)——Host by BJTU
【思路】
斜率优化+分配式DP。
设f[i][j]表示将前i个分作j个集合所得最小消费,则有转移方程式:
f[i][j]=min{ f[k][j-1]+(A[k]-A[j+1])^2 }
若有k>l,且决策k优于决策l则有:
f[k][j-1]-f[l][j-1]+sq(A[k+1])-sq(A[l+1]) <= 2*(A[k+1]-A[l+1])*A[i]
先进行j循环枚举f[][j],每一层维护一个单调队列即可。
乘除耗费时间悬殊,如果直接除这个题就超时了。
【代码】
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; typedef double Do; const int N = 1e4+10; const int M = 5000+10; int f [M],A ,q ; int n,m,L,R; int sq(int x) { return x*x; } int UP(int l,int k,int j) { return f[k][j-1]-f[l][j-1]+sq(A[k+1])-sq(A[l+1]); } int DN(int l,int k,int j) { return 2*(A[k+1]-A[l+1]); } void read(int& x) { char c=getchar(); while(!isdigit(c)) c=getchar(); x=0; while(isdigit(c)) x=x*10+c-'0' , c=getchar(); } int main() { int T,kase=0; read(T); while(T--) { read(n),read(m); for(int i=1;i<=n;i++) read(A[i]); sort(A+1,A+n+1); for(int i=1;i<=n;i++) f[i][1]=sq(A[i]-A[1]); //初始化第一层 for(int j=2;j<=m;j++) { L=R=0; for(int i=1;i<=n;i++) { while(L<R && UP(q[L],q[L+1],j)<=A[i]*DN(q[L],q[L+1],j)) L++; int t=q[L]; f[i][j]=f[t][j-1]+sq(A[i]-A[t+1]); while(L<R && UP(q[R-1],q[R],j)*DN(q[R],i,j)>=UP(q[R],i,j)*DN(q[R-1],q[R],j)) R--; q[++R]=i; } } printf("Case %d: %d\n",++kase,f [m]); } return 0; }
相关文章推荐
- (一〇八)第八章编程练习
- (一〇七)第八章复习题
- Java [Leetcode 326]Power of Three
- [6]姥爷幽默谈Objective-C-文件操作类NSFileManager,NSFileHandle
- C语言 关键字、标识符、注释
- 【项目】Nuget更新
- 简易在线投票系统(php)——主页获取信息
- 大话设计模式 第二章 策略模式 C++实现
- 常见Python运行时错误
- getApplicationContext()、getBaseContext()和Activity.this区别
- myeclipse/eclipse安装反编译插件jadclipse
- yum 常用操作
- greenDAO简介
- myeclipse/eclipse安装反编译插件jadclipse
- android WindowManager addView Demo
- 机器学习系列(6)_从白富美相亲看特征预处理与选择(下)
- 机器学习系列(6)_从白富美相亲看特征预处理与选择(下)
- python解析C语言结果
- dedeCMS修改文章更新发布时间问题
- printf缓存问题