HDU-3480 Division (四边形不等式优化DP)
2024-09-28 08:13:40
题目大意:将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)满足凸四边形不等式。
代码如下:
# 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][n];
} int main()
{
int T,cas=0;
scanf("%d",&T);
while(T--)
{
read();
printf("Case %d: %d\n",++cas,solve());
}
return 0;
}
最新文章
- Worktile协同特色之二:任务看板管理
- Nginx配置文件说明
- Extjs API - JS Duck
- c++性能测试
- Hyper Prefix Sets
- windows环境搭建jira 详解
- trycatch放在for循环的里面还是外面好
- vue-cli脚手架npm相关文件解读(5)vue-loader.conf.js
- js的继承实现
- 《前端之路》之五 head 头标签指南
- 查看 FormData 中已存在的值
- 举例跟踪linux内核系统调用
- Win2008服务启动不能调用Office Word的解决方法
- CF1101G (Zero XOR Subset)-less
- 『TensorFlow Internals』笔记_源码结构
- First C++
- 读jQuery源码释疑笔记
- 开源项目MultiChoiceAdapter详解(四)——MultiChoiceBaseAdapter的使用
- c#使用QQ邮箱的SSL收发邮件
- 学习 Linux,302(混合环境): 概念
热门文章
- shell字符串操作技巧
- kafka生产者和消费者
- ELK学习笔记之CentOS 7下ELK(6.2.4)++LogStash+Filebeat+Log4j日志集成环境搭建
- bzoj1660 / P2866 [USACO06NOV]糟糕的一天Bad Hair Day
- Python descriptor 以及 内置property()函数
- 使用CloudFlare 的 PKI 工具集 cfssl 来生成 Certificate Authority (CA) 证书和秘钥文件
- 20145302张薇 《网络对抗技术》 web基础
- 将kali linux装入U盘 制作随身携带的kali linux
- mips32和x86下的大小端模式判定
- PHP开发者的路书