• 1048 石子归并


    题目描述 Description

    有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1]。问安排怎样的合并顺序,能够使得总合并代价达到最小。

    输入描述 Input Description

    第一行一个整数n(n<=100)

    第二行n个整数w1,w2...wn  (wi <= 100)

    输出描述 Output Description

    一个整数表示最小合并代价

    样例输入 Sample Input

    4

    4 1 1 4

    样例输出 Sample Output

    18

    一道典型的区间型dp。

    我们可以设dp[i][j]表示从第i堆(包含i)到第j堆(包含j)石子的合并的最小代价。我们可以写出状态转移方程为:

    dp[i][j] = min{dp[i][k] + dp[k+1][j] + sum[j] - sum[i-1]}, i <= k < j (i !+ j)

    附AC代码:

     1 #include<iostream>
     2 #include<cmath>
     3 #include<cstring>
     4 using namespace std;
     5 
     6 const int INF=1<<30; 
     7 const int MAXV=110;
     8 
     9 int dp[MAXV][MAXV];
    10 int sum[MAXV];
    11 int w[MAXV];
    12 
    13 int main(){
    14     int n;
    15     while(cin>>n){
    16         memset(sum,0,sizeof(sum));
    17         for(int i=1;i<=n;i++){
    18             cin>>w[i];
    19             sum[i]=sum[i-1]+w[i];
    20             dp[i][i]=0;//在t==2时会用到 
    21         }
    22         for(int t=2;t<=n;t++){//表示合并的区间长度 即i~j(包括i,j) 
    23             for(int i=1;i<=n;i++){
    24                 int j=i+t-1;//由于包含j故减一 
    25                 int MAX=INF;
    26                 for(int k=i;k<j;k++){
    27                     if(MAX>dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1])//状态方程 
    28                     MAX=dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1];
    29                 }
    30                 dp[i][j]=MAX;//存入dp 
    31             }
    32         }
    33         cout<<dp[1][n]<<endl;
    34     }
    35     return 0;
    36 }
  • 相关阅读:
    Java 学习笔记(10)——容器
    Java 学习笔记(9)——java常用类
    Java 学习笔记(8)——匿名对象与内部类
    OGC相关概念解析
    Django中URL有关
    转载关于Python Web后端开发面试心得
    ArcPy中mapping常见函数及用法1
    Django1.11加载静态文件
    ArcPy第一章-Python基础
    浅谈提高Django性能
  • 原文地址:https://www.cnblogs.com/Kiven5197/p/5682494.html
Copyright © 2020-2023  润新知