zoukankan      html  css  js  c++  java
  • 洛谷 P1880 [NOI1995]石子合并

    链接https://www.luogu.org/problem/P1880

    思路区间dp,只不过是环上的,把整个序列复制一份就好了。

    dp[l][r]表示l到r的最大/小值,状态转移方程就是dp[l][r]=max/min{dp[l][k]+dp[k+1][r] | l<=k<r}+sum[r]-sum[l-1],啥意思呢,就是把l到r的区间分成两部分,一部分是l到k,另一部分是k+1到r,( l到r的最值 )就等于( ( l到k的最值 ) 加 ( k+1到r的最值 ) )的最值 再加上 ( l到r的元素和 ) ,具体证明不赘述因为我不会。枚举的时候先枚举区间长度,再枚举区间左端点,最后枚举k的下标,几乎就是区间dp的模板

    代码

     1 //
     2 //                       _oo0oo_
     3 //                      o8888888o
     4 //                      88" . "88
     5 //                      (| -_- |)
     6 //                      0  =  /0
     7 //                    ___/`---'\___
     8 //                  .' \|     |// '.
     9 //                 / \|||  :  |||// 
    10 //                / _||||| -:- |||||- 
    11 //               |   | \  -  /// |   |
    12 //               | \_|  ''---/''  |_/ |
    13 //                 .-\__  '-'  ___/-. /
    14 //             ___'. .'  /--.--  `. .'___
    15 //          ."" '<  `.___\_<|>_/___.' >' "".
    16 //         | | :  `- \`.;` _ /`;.`/ - ` : | |
    17 //            `_.   \_ __ /__ _/   .-` /  /
    18 //     =====`-.____`.___ \_____/___.-`___.-'=====
    19 //                       `=---='
    20 //
    21 //
    22 //     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    23 //
    24 //               佛祖保佑         永无BUG
    25 //
    26 //
    27 //
    28  
    29 // #include<bits/stdc++.h>
    30 #include<iostream>
    31 #include<cstdio>
    32 #include<cmath>
    33 #include<string>
    34 #include<vector>
    35 #include<algorithm>
    36 #include<queue>
    37 #include<deque>
    38 #include<stack>
    39 #include<map>
    40 #include<cstring>
    41 
    42 #define inf 0x3f3f3f3f
    43 using namespace std;
    44  
    45 typedef long long ll;
    46 typedef long double ld;
    47  
    48 const int M = int(1e5)*3 + 5;
    49 const int mod = 10056;
    50  
    51 inline int lowbit(int x) {
    52     return x & (-x);
    53 }
    54 
    55 int a[M];
    56 int sum[M];
    57 int dp_max[1005][1005];
    58 int dp_min[1005][1005];
    59 int minn,maxn;
    60 int main()
    61 {
    62     memset(dp_min,inf,sizeof(dp_min));
    63     memset(dp_max,-inf,sizeof(dp_max));
    64     int n;cin>>n;
    65     for(int i=1;i<=n;i++){
    66         cin>>a[i];
    67         a[i+n]=a[i];
    68     }
    69     for(int i=1;i<=n+n;i++){
    70         sum[i]=sum[i-1]+a[i];
    71         dp_min[i][i]=0;//自己合并自己就是0
    72         dp_max[i][i]=0;//自己合并自己就是0
    73     }
    74 
    75     for(int len=2;len<=n;len++){
    76         for(int l=1;l<=n+n-len+1;l++){
    77             int r=l+len-1;
    78             for(int k=l;k<r;k++){
    79                 dp_max[l][r]=max(dp_max[l][r],dp_max[l][k]+dp_max[k+1][r]);
    80                 dp_min[l][r]=min(dp_min[l][r],dp_min[l][k]+dp_min[k+1][r]);
    81             }
    82             dp_min[l][r]+=(sum[r]-sum[l-1]);
    83             dp_max[l][r]+=(sum[r]-sum[l-1]);
    84         }
    85     }
    86 
    87     minn=inf;maxn=-inf;
    88     for(int i=1;i<=n;i++){
    89         minn=min(minn,dp_min[i][i+n-1]);
    90         maxn=max(maxn,dp_max[i][i+n-1]);
    91     }
    92 
    93     cout<<minn<<endl<<maxn<<endl;
    94     return 0;
    95 }

    备注急需一名OI爷带我进final

  • 相关阅读:
    【剑指offer】对称的二叉树
    【剑指offer】数组中的逆序对
    【剑指offer】不用加减乘除做加法
    【剑指offer】和为S的连续正数序列
    【剑指offer】删除链表中重复的结点
    【剑指offer】平衡二叉树
    Math.ceil()、Math.floor()和Math.round()
    document.querySelectorAll遍历
    JS选择器querySelector和~All,三个原生选择器
    js 操作select和option常见用法
  • 原文地址:https://www.cnblogs.com/harutomimori/p/11288549.html
Copyright © 2011-2022 走看看