zoukankan      html  css  js  c++  java
  • nyoj-737--石子合并(一)(动态规划)

    石子合并(一)

    时间限制:1000 ms  |  内存限制:65535 KB
    难度:3
    描述
        有N堆石子排成一排,每堆石子有一定的数量。现要将N堆石子并成为一堆。合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆。求出总的代价最小值。
    输入
    有多组测试数据,输入到文件结束。
    每组测试数据第一行有一个整数n,表示有n堆石子。
    接下来的一行有n(0< n <200)个数,分别表示这n堆石子的数目,用空格隔开
    输出
    输出总代价的最小值,占单独的一行
    样例输入
    3
    1 2 3
    7
    13 7 8 16 21 4 18
    样例输出
    9
    239
    来源
    经典问题
    上传者

    TC_胡仁东



    /*dp数组中存放合并i--j所需要的最少代价,局部最优达到整体最优,刚开始
    从一个到两个*/
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    #define MAX 0x3f3f3f
    int dp[210][210];
    int a[210];
    int sum[210];
    int main()
    {
    	int n;
    	while(scanf("%d",&n)!=EOF)
    	{
    		memset(sum,0,sizeof(sum));
    		for(int i=1;i<=n;i++)
    		{
    			scanf("%d",&a[i]);
    			sum[i]=sum[i-1]+a[i];
    		}
    		memset(dp,0,sizeof(dp));
    		for(int i=n;i>=1;i--)
    		{
    			for(int j=i+1;j<=n;j++)
    			//i和j固定了起点和终点,k相当于节点,通过变换k来达到i--j最优 
    			{
    				int temp=MAX;
    				for(int k=i;k<j;k++)//k!=j,因为同一堆石子不能合并 
    				temp=min(temp,dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);
    				dp[i][j]=temp;
    			}
    		}
    		printf("%d
    ",dp[1][n]);
    	}
    	return 0;
    }



  • 相关阅读:
    Codeforces Round #594 (Div. 2) ABC题
    Codeforces Round #596 (Div. 2) ABCD题
    数据结构实验5——二叉树
    数据结构实验4——字符串匹配
    数据结构实验3——用栈求解算术表达式
    友链
    Codeforces Round #577 (Div. 2)
    Educational Codeforces Round 70 (Rated for Div. 2)
    Codeforces Round #578 (Div. 2)
    2020 Multi-University Training Contest 10(待补
  • 原文地址:https://www.cnblogs.com/playboy307/p/5273712.html
Copyright © 2011-2022 走看看