zoukankan      html  css  js  c++  java
  • Luogu P1880 石子合并 题解报告

    题目传送门

    【题目大意】

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

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

    【思路解析】

    首先是断环为链,这题数据不大,没什么问题。

    说一下转移方程吧$$f[l][r]=min(f[l][r],f[l][k]+f[k+1][r])+sum[r]-sum[l-1](lle k<r)$$初始值:详见代码

    目标:$min(f[i][i+n-1])(iin[1,n]),max(g[i][i+n-1])(iin[1,n])$.

    还有就是要注意一下循环嵌套的顺序,哪一个循环在里面,哪一个循环在外面。

    【代码实现】

     1 #include<bits/stdc++.h>
     2 #define rg register
     3 #define go(i,a,b) for(rg int i=a;i<=b;i++)
     4 #define back(i,a,b) for(rg int i=a;i>=b;i--)
     5 #define mod 2147483648
     6 #define ll long long
     7 using namespace std;
     8 const int N=102<<1;
     9 int n,a[N],sum[N];
    10 ll f[N][N],g[N][N];
    11 int main(){
    12     scanf("%d",&n);
    13     memset(f,0x3f,sizeof(f));memset(g,0,sizeof(g));
    14     go(i,1,n) scanf("%d",&a[i]),a[i+n]=a[i];
    15     go(i,1,n*2) f[i][i]=0,g[i][i]=0,sum[i]=sum[i-1]+a[i];
    16     go(len,2,n) go(l,1,2*n-len+1){
    17         int r=l+len-1;
    18         go(k,l,r-1){
    19             f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]);
    20             g[l][r]=max(g[l][r],g[l][k]+g[k+1][r]);
    21         }
    22         f[l][r]+=sum[r]-sum[l-1];
    23         g[l][r]+=sum[r]-sum[l-1];
    24     }
    25     ll ans1=123456798,ans2=0;
    26     go(i,1,n) ans1=min(ans1,f[i][i+n-1]),ans2=max(ans2,g[i][i+n-1]);
    27     printf("%lld
    %lld
    ",ans1,ans2);
    28     return 0;
    29 }
    代码戳这里
  • 相关阅读:
    random模块
    时间模块
    内置函数
    装饰器函数
    python基础二
    linux Ubuntu 16.04安装 postgresql
    Winfrom中的几种传值方式
    C#6.0新特性
    Treeview显示磁盘下的文件,并且可操作
    C#,ASP.NET简单的MD5加密,解密
  • 原文地址:https://www.cnblogs.com/THWZF/p/10996380.html
Copyright © 2011-2022 走看看