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

    这么水的题不想水博客来着,但是感觉这种把原序列倍增后,进行区间DP的思路很奇妙,记录一下。

    因为是一个环,所以对原序列倍增后,再进行DP,最后枚举起始位置。

    dp[i][j]表示[i,j]这一段合并产生的最大/最小价值。

     1 #include <cstdio>
     2 #include <algorithm>
     3 using namespace std;
     4 typedef long long ll;
     5 int n;
     6 ll vec[220],res[2];
     7 ll dp[220][220][2];
     8 ll dfs(int l,int r,int opt)
     9 {
    10     if (dp[l][r][opt] != 0 || l == r)
    11         return dp[l][r][opt];
    12     if (opt == 0)
    13         dp[l][r][opt] = 100000000000000;
    14     for (int i = l;i <= r - 1;i++)
    15         if (opt == 1)
    16             dp[l][r][opt] = max(dfs(l,i,opt) + dfs(i + 1,r,opt),dp[l][r][opt]);
    17         else
    18             dp[l][r][opt] = min(dfs(l,i,opt) + dfs(i + 1,r,opt),dp[l][r][opt]);
    19     dp[l][r][opt] += vec[r] - vec[l - 1];
    20     return dp[l][r][opt];
    21 }
    22 int main()
    23 {
    24     scanf("%d",&n);
    25     for (int i = 1;i <= n;i++)
    26         scanf("%lld",&vec[i]);
    27     for (int i = n + 1;i <= 2 * n;i++)
    28         vec[i] = vec[i - n];
    29     for (int i = 1;i <= 2 * n;i++)
    30         vec[i] += vec[i - 1];
    31     res[0] = 100000000000000;
    32     for (int i = 1;i <= n + 1;i++)
    33     {
    34         res[0] = min(res[0],dfs(i,i + n - 1,0));
    35         res[1] = max(res[1],dfs(i,i + n - 1,1));
    36     }
    37     printf("%lld
    %lld
    ",res[0],res[1]);
    38     return 0;
    39 }
    心之所动 且就随缘去吧
  • 相关阅读:
    重构第30天 尽快返回 (Return ASAP)
    Thingsboard MQTT连接至服务器
    Thingsboard学习之三启动Thingsboard
    Thingsboard学习之二安装Docker和Docker-Compose
    Thingsboard学习之一CentOS安装系统更新
    CentOS 修改固定IP地址
    macbook配置homebrew
    macbook配置flutter环境变量
    Linux单独打包工具-Ubuntu
    postman测试API
  • 原文地址:https://www.cnblogs.com/iat14/p/10565994.html
Copyright © 2011-2022 走看看