zoukankan      html  css  js  c++  java
  • csu 1592(区间DP)

    1592: 石子归并

    Time Limit: 1 Sec  Memory Limit: 128 MB
    Submit: 356  Solved: 148
    [Submit][Status][Web Board]

    Description

    现在有n堆石子,第i堆有ai个石子。现在要把这些石子合并成一堆,每次只能合并相邻两个,每次合并的代价是两堆石子的总石子数。求合并所有石子的最小代价。

    Input

    第一行包含一个整数T(T<=50),表示数据组数。
    每组数据第一行包含一个整数n(2<=n<=100),表示石子的堆数。
    第二行包含n个正整数ai(ai<=100),表示每堆石子的石子数。

    Output

    每组数据仅一行,表示最小合并代价。

    Sample Input

    2
    4
    1 2 3 4
    5
    3 5 2 1 4

    Sample Output

    19
    33

    dp[i][j]代表合并第 i-j 堆石子所需最小代价,枚举区间长度即可.dp[i][j] = min(dp[i][k]+dp[k+1][j]+sum(i,j)) i<=k<j .sum(i,j) 代表合并第i堆到第j堆石子所需代价。
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include <string.h>
    #include <math.h>
    using namespace std;
    const int INF = 999999999;
    int n,sum[105],dp[105][105]; ///dp[i][j]代表合并第 i 堆石子到第 j 堆石子最小费用
    int main(){
        int tcase;
        scanf("%d",&tcase);
        while(tcase--){
            scanf("%d",&n);
            sum[0] = 0;
            for(int i=1;i<=n;i++){
                int v;
                scanf("%d",&v);
                sum[i] = sum[i-1]+v;
            }
            memset(dp,0,sizeof(dp));
            for(int l=1;l<=n;l++){
                for(int i=1;l+i<=n;i++){
                    int j = i+l;
                    dp[i][j]= INF;
                    for(int k=i;k<j;k++){
                        dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);
                    }
                }
            }
            printf("%d
    ",dp[1][n]);
        }
    }
    
    
  • 相关阅读:
    经典脚本集合
    Crystal Report 注册号
    Linux top命令简介
    sysctl.conf优化方案(完整)
    vi入门学习(转载)
    linux 如何查看目录的剩余空间大小?
    python3安装pip3
    jsonCpp的readme文档
    第15天android:使用sqlite
    《mysql必知必会》笔记
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5791206.html
Copyright © 2011-2022 走看看