• 石子归并


     

    【思路】

     我们 dp[i][j] 来表示合并第 i 堆到第 j 堆石子的最小代价。

     那么状态转移方程为  dp[i][j] = min ( dp[i][j],dp[i][k]+dp[k+1][j]+w[i][j]);

    其中, w[i][j] 表示把两部分合并起来的代价,即从第 i 堆到第 j 堆石子个数的和,为了方便查询,我们可以用 sum[i] 表示从第1堆到第i堆的石子个数和,那么 w[i][j]=sum[j]-sum[i-1].(前缀和思想)

    AC_Code:

     1 #include <bits/stdc++.h>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <string>
     5 #include <cmath>
     6 #include <queue>
     7 #include <stack>
     8 #include <vector>
     9 #include <set>
    10 #include <map>
    11 #include <algorithm>
    12 using namespace std;
    13 typedef long long ll;
    14 const int maxn=205;
    15 const ll mod=1e9+7;
    16 const ll INF=1e18;
    17 const double eps = 1e-9;
    18 
    19 int n,x;
    20 int sum[maxn];
    21 int dp[maxn][maxn];///合并第i堆到第j堆石子的最小代价
    22 int main()
    23 {
    24     while(~scanf("%d",&n)){
    25         sum[0]=0;
    26         memset(dp,0x3f,sizeof(dp));
    27         for(int i=1;i<=n;i++){
    28             scanf("%d",&x);
    29             sum[i]=sum[i-1]+x;
    30             dp[i][i]=0;
    31         }
    32         for(int len=2;len<=n;len++){
    33             for(int i=1;i<=n;i++){
    34                 int j=i+len-1;
    35                 if( j>n ) continue;
    36                 for(int k=i;k<j;k++){
    37                     dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+(sum[j]-sum[i-1]));
    38                 }
    39             }
    40         }
    41         printf("%d
    ",dp[1][n]);
    42     }
    43     return 0;
    44 }

    平行四边形优化】:详解

     1 #include <bits/stdc++.h>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <string>
     5 #include <cmath>
     6 #include <queue>
     7 #include <stack>
     8 #include <vector>
     9 #include <set>
    10 #include <map>
    11 #include <algorithm>
    12 using namespace std;
    13 typedef long long ll;
    14 const int maxn=205;
    15 const ll mod=1e9+7;
    16 const ll INF=1e18;
    17 const double eps = 1e-9;
    18 
    19 int n,x;
    20 int sum[maxn];
    21 int dp[maxn][maxn];///合并第i堆到第j堆石子的最小代价
    22 int s[maxn][maxn];
    23 int main()
    24 {
    25     while(~scanf("%d",&n)){
    26         sum[0]=0;
    27         memset(dp,0x3f,sizeof(dp));
    28         for(int i=1;i<=n;i++){
    29             scanf("%d",&x);
    30             sum[i]=sum[i-1]+x;
    31             dp[i][i]=0;
    32             s[i][i]=i;
    33         }
    34         for(int len=2;len<=n;len++){
    35             for(int i=1;i<=n;i++){
    36                 int j=i+len-1;
    37                 if( j>n ){
    38                     continue;
    39                 }
    40                 for(int k=s[i][j-1];k<=s[i+1][j];k++){
    41                     if( dp[i][k]+dp[k+1][j]+(sum[j]-sum[i-1])<dp[i][j] ){
    42                         dp[i][j]=dp[i][k]+dp[k+1][j]+(sum[j]-sum[i-1]);
    43                         s[i][j]=k;
    44                     }
    45                 }
    46             }
    47         }
    48         printf("%d
    ",dp[1][n]);
    49     }
    50     return 0;
    51 }
  • 相关阅读:
    Codeforces F. Bits And Pieces(位运算)
    一场comet常规赛的台前幕后
    【NOIP2019模拟2019.9.4】B(期望的线性性)
    「NOI2016」循环之美(小性质+min_25筛)
    【NOI2011】兔农(循环节)
    LOJ #6538. 烷基计数 加强版 加强版(生成函数,burnside引理,多项式牛顿迭代)
    noi2019感想
    7.12模拟T2(套路容斥+多项式求逆)
    CF 848E(动态规划+分治NTT)
    CF 398 E(动态规划)
  • 原文地址:https://www.cnblogs.com/wsy107316/p/12251312.html
Copyright © 2020-2023  润新知