【原】动态规划——石子划分问题

简介:

描述



输入格式

第一行两个正整数n和m,接下来一行有n个正整数,表示一个石子的重量ai。(1≤n, m, ai≤1000)

 

输出格式

计算输出最小总划分费用。

注意:若只有一个石子一份,那么,这份石子中最大重量与最小重量的差的平方为0。

 

输入样例

4 2
4 7 10 1

 

输出样例

18
///////////////////////////////////////////////////////////////////////

复制代码
 1 /********************************************
 2 程序总体思想
 3 
 4 1,先将石子重量从小到大排序(从大到小也可以).
 5 2,假设f(n,m)表示:n个石头分成m份的最小费用. 特别的,有f(1,1)=0; f(n,1)=(an - a1)^2
 6 那么,除去最后一份石头的若干个,前面m-1份必定也是最优的分法.
 7 若最后一堆1个石头, f(n,m) = f(n-1,m-1)+0^2
 8 若最后一堆2个石头, f(n,m) = f(n-2,m-1)+(an - an-1)^2
 9 若最后一堆3个石头, f(n,m) = f(n-3,m-1)+(an - an-2)^2
10 ......
11 最后一堆最多只能有n-m+1个石头,因为当最后一堆为n-m+1时,前面m-1堆已经是一个一份了.
12 因此, f(n,m) = Min{ f(n-1,m-1)+0^2,  f(n-2,m-1)+(an - an-1)^2,  ...}
13 
14   例如:
15   n=5, m=2
16   a[1..5] = 1 3 4 8 9
17   f(5,2)=Min{ f(4,1)+0; f(3,1)+1; f(2,1)+5^2 }=Min{49,10,29}=10
18 这5个石头分2堆的最优分法:(1 3 4)(8 9)
19 
20 ********************************************/
21 
22 
23 
24 #include "StdAfx.h"
25 #include <algorithm>
26 #include <iostream>
27 #include <stdio.h>
28 
29 using namespace std;
30 
31 #define MAX_NUM 10000000  
32 // d[i][j]表示从i到n分成j份的最小划分费用,i=0 或 j=0不用
33 
34 inline int Min(int a,int b)
35 {
36     if(a>b)
37         return b;
38     else
39         return a;
40 }
41 
42 int Divide(const int list[],const int &totalNum, const int &divCount,const int &list_length)
43 {
44     int i,j,k,t;
45     int d_size = list_length + 1;// i,j=0的时候不用
46     int **d = new int *[d_size];
47     for (i = 0; i < d_size; i++)
48     {
49         d[i] = new int[d_size];
50     }
51     
52     for(i=1;i<=totalNum;i++)
53     {
54         d[i][1]=(list[i]-list[1])*(list[i]-list[1]);
55         t=Min(i,divCount);
56         for(j=2;j<=t;j++)
57         {  
58             d[i][j]=MAX_NUM;
59             for(k=1;k<i;k++)
60             {
61                 d[i][j]=Min(d[i][j],d[k][j-1]+(list[i]-list[k+1])*(list[i]-list[k+1]));    //    重点
62             //    cout<<d[i][j]<<"\n";
63             }
64         }
65     }
66     
67     int minCost = d[totalNum][divCount];
68     //    释放二维数组内存
69     for (i = 0; i < d_size; i++)
70     {
71         delete[] d[i];
72     }
73     delete []d;
74     
75     return minCost;
76 }
77 
78 int main()
79 {
80     //    石头数、份数
81     int totalNum, divCount, weight, i, minDivCost = 0;
82     cin>>totalNum>>divCount;
83     //    list[0]不用
84     int *list = new int[totalNum+1];
85     for (i = 1; i <= totalNum; i++)
86     {
87         cin>>weight;
88         list[i] = weight;
89     }
90     sort(list+1, list + totalNum+1);
91     minDivCost = Divide(list, totalNum, divCount, totalNum);
92     cout<<minDivCost<<endl;
93 
94     delete []list;
95     return 0;
96 }
复制代码

 本文转自编程小翁博客园博客,原文链接:http://www.cnblogs.com/wengzilin/archive/2012/10/16/2726262.html,如需转载请自行联系原作者

相关文章
|
JavaScript 前端开发 安全
前端实践:如何防止xss跨站脚本攻击(vue代码说明)
XSS(跨站脚本)攻击是一种常见的网络安全漏洞,攻击者通过在网页中注入恶意脚本代码,从而实现窃取用户信息、盗取会话令牌等攻击目的。为了防止XSS攻击,我们可以采取以下措施:
7453 0
前端实践:如何防止xss跨站脚本攻击(vue代码说明)
|
6月前
|
负载均衡 Java Nacos
Spring Cloud五大组件
Spring Cloud五大组件
|
11月前
|
算法 Java 数据库
美团面试:百亿级分片,如何设计基因算法?
40岁老架构师尼恩在读者群中分享了关于分库分表的基因算法设计,旨在帮助大家应对一线互联网企业的面试题。文章详细介绍了分库分表的背景、分片键的设计目标和建议,以及基因法的具体应用和优缺点。通过系统化的梳理,帮助读者提升架构、设计和开发水平,顺利通过面试。
美团面试:百亿级分片,如何设计基因算法?
|
XML 设计模式 Java
这6种 Spring 依赖注入方式,你都会吗?
这6种 Spring 依赖注入方式,你都会吗?
1888 1
这6种 Spring 依赖注入方式,你都会吗?
|
缓存 负载均衡 安全
|
负载均衡 Java 容器
@LoadBalanced注解RestTemplate拥有负载均衡的能力
@LoadBalanced注解RestTemplate拥有负载均衡的能力
@LoadBalanced注解RestTemplate拥有负载均衡的能力
|
Java API Apache
如何在Java中实现图片处理
如何在Java中实现图片处理
|
存储 运维 SpringCloudAlibaba
SpringCloud Alibaba微服务运维一 - 集成SkyWalking
SpringCloud Alibaba微服务运维一 - 集成SkyWalking
1078 0
|
存储 消息中间件 缓存
阿里IM技术分享(十):深度揭密钉钉后端架构的单元化演进之路
今天想借此文和大家分享我们在钉钉单元化架构实施过程中的心路历程和一些最佳实践。因涉及的技术和业务面太广,本文的分享无法做到面面俱到,主要是想在同路人中形成共鸣,进而能复用一些架构或子系统的设计和实现思路。
1263 1
阿里IM技术分享(十):深度揭密钉钉后端架构的单元化演进之路