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


    描述



    输入格式

    第一行两个正整数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 }









  • 相关阅读:
    jQuery选择器大全(48个代码片段+21幅图演示)
    抽象和模型
    什么叫做精通,我来给大家解释一下
    设置浏览器固定大小的固定位置的方法
    selenium对浏览器属性操作的方法
    selenium 最大化浏览器是解决浏览器和驱动不匹配的方法如下
    java selenium手动最大化chrome浏览器的方法
    java selenium启动火狐浏览器报错:Cannot find firefox binary in PATH. Make sure firefox is installed. OS appears to be: VISTA Build info: version: '3.8.1', revision: '6e95a6684b', time: '2017-12-01T19:05:14.666Z
    mygenerator().next() AttributeError: 'generator' object has no attribute 'next'
    马的遍历 搜索
  • 原文地址:https://www.cnblogs.com/wengzilin/p/2726262.html
Copyright © 2020-2023  润新知