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
  • 相关阅读:
    Eclipse对printf()不能输出到控制台的解决方法
    Eclipse launch failed.Binary not found解决方案
    Windows 7中使用Eclipse 使用CDT and WinGW 开发C/C++(转载)
    assets
    方法对头,报表模板维护其实很简单
    刷机包各个文件都是啥
    开机logo切换逻辑深入研究
    不同分辨率的LCM进行兼容
    SD卡驱动分析(二)
    SD卡驱动分析(一)
  • 原文地址:https://www.cnblogs.com/-xiangyang/p/9387813.html
Copyright © 2011-2022 走看看