zoukankan      html  css  js  c++  java
  • P1880 [NOI1995]石子合并【区间DP】

    题目描述

    在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。

    试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分.

    输入输出格式

    输入格式:

    数据的第1行试正整数N,1≤N≤100,表示有N堆石子.第2行有N个数,分别表示每堆石子的个数.

    输出格式:

    输出共2行,第1行为最小得分,第2行为最大得分.

    输入输出样例

    输入样例#1: 

    4
    4 5 9 4

    输出样例#1:

    43
    54
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int MAXN=310;
     4 const int INF=0x3f3f3f3f;
     5 int dp[MAXN][MAXN],sum[MAXN],ans[MAXN],DP[MAXN][MAXN];
     6 int jian(int i,int j){ return sum[j]-sum[i-1]; }//i-1是因为前缀和要减去前一个而不是当前的那个。
     7 int main()
     8 {
     9     int n;
    10     scanf("%d",&n);
    11     for (int i = 1; i <=n ; ++i) {
    12         scanf("%d",&ans[i]);
    13     }
    14     for (int i = 1; i <=n+n ; ++i) {//拆开环,双向
    15         ans[i+n]=ans[i];
    16         sum[i]=ans[i]+sum[i-1];//前缀和
    17     }
    18     memset(dp,0, sizeof(dp));
    19     for (int l = 1; l <n ; ++l) {// 步长 ,l==1时,步长为二
    20         for (int i = 1,j=i+l; (j<n+n)&&(i<n+n) ; ++i,j=i+l) {
    21             DP[i][j]=INF;
    22             for (int k = i; k <j ; ++k) {//每一步当中的分割点
    23                 dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+jian(i,j));//l-r的最大值
    24                 DP[i][j]=min(DP[i][j],DP[i][k]+DP[k+1][j]+jian(i,j));
    25             }
    26         }
    27     }
    28     int MAX=0,MIN=INF;
    29     for(int i=1;i<=n;i++)
    30     {
    31         MAX=max(MAX,dp[i][i+n-1]);
    32         MIN=min(MIN,DP[i][i+n-1]);
    33     }
    34     printf("%d
    %d
    ",MIN,MAX);
    35     return 0;
    36 }
    View Code
  • 相关阅读:
    Vue学习之路5-v-model指令
    Vue学习之路4-v-bind指令
    Laravel 中的 Many-To-Many
    laravel获取checkbox值的小技巧
    查看 Laravel 的 SQL 语句的方法
    那些好用的插件(持续更新)
    写代码原则
    Laravel 5.5 Blade::if 简介
    Laravel 项目使用 Carbon 人性化显示文章发表时间
    php7简短而安全的数组遍历方法
  • 原文地址:https://www.cnblogs.com/-xiangyang/p/9387813.html
Copyright © 2011-2022 走看看