HDU-3480 Division (四边形不等式优化DP)
2016-03-19 11:12
381 查看
题目大意:将n个数分成m组,将每组的最大值与最小值的平方差加起来,求最小和。
题目分析:先对数排序。定义状态dp(i,j)表示前 j 个数分成 i 组得到的最小和,则状态转移方程为dp(i,j)=min(dp(i,k-1)+w(k,j)),其中w(i,j)=(a[i]-s[j])*(a[i]-a[j])。很显然,dp(i,j)满足凸四边形不等式。
代码如下:
题目分析:先对数排序。定义状态dp(i,j)表示前 j 个数分成 i 组得到的最小和,则状态转移方程为dp(i,j)=min(dp(i,k-1)+w(k,j)),其中w(i,j)=(a[i]-s[j])*(a[i]-a[j])。很显然,dp(i,j)满足凸四边形不等式。
代码如下:
# include<iostream> # include<cstdio> # include<cstring> # include<algorithm> using namespace std; const int INF=1<<30; int dp[10005][505]; int K[10005][505]; int a[10005]; int n,m; void read() { scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) scanf("%d",a+i); } int solve() { sort(a+1,a+n+1); for(int i=1;i<=n;++i){ dp[1][i]=(a[i]-a[1])*(a[i]-a[1]); K[1][i]=0; if(i<=m){ dp[i][i]=0; K[i][i]=i; } } for(int i=2;i<=m;++i){ K[i][n+1]=n; for(int j=n;j>=i;--j){ dp[i][j]=INF; for(int k=K[i-1][j];k<=K[i][j+1];++k){ if(dp[i][j]>dp[i-1][k-1]+(a[j]-a[k])*(a[j]-a[k])){ dp[i][j]=dp[i-1][k-1]+(a[j]-a[k])*(a[j]-a[k]); K[i][j]=k; } } } } return dp[m] ; } int main() { int T,cas=0; scanf("%d",&T); while(T--) { read(); printf("Case %d: %d\n",++cas,solve()); } return 0; }
相关文章推荐
- MAC 如何设置文件夹权限为777
- 序列自增长
- How to fix and recover a “corrupt history file” in zsh?
- 数据恢复软件 整理
- 程序员的绘图利器 — Graphviz - zhangskd的专栏 - 博客频道 - CSDN.NET
- 微信红包实现原理[转]
- Windows|Eclipse 运行HDFS程序遇到问题之 AccessControlException
- 【Android学习】动态文字闪动效果
- 剑指offer:求二叉树的深度
- 3*1的骨骼牌排列
- 绘图工具graphviz学习使用 - 推酷
- 在 Tomcat 中配置 SSL/TLS 以支持 HTTPS
- 把github作为私密代码管理仓库
- dedecms likearticle 调用附加表的字段调用方式
- ClassyShark:轻便的安卓可执行文件浏览器
- 一段代码学习几个Python知识点
- leetcode-338-Counting Bits
- http异步请求
- hdu 3652 B-number
- 栈的链式存储(含源码)