• BZOJ 4897


    这题感觉真是太神了....

    看了网上很多题解,最后参考了这个:http://blog.csdn.net/hld67890/article/details/72556554

    首先我们容易想到区间DP,令DP[i][j]表示将[i,j]这段区间全部取完的最小代价,那么我们要如何转移呢?我们发现DP[i][j]的转移过程其实是在[i,j]中选一个子序列,然后我们将这个区间取成只剩这个子序列,然后再将这个子序列取走。这样我们就需要DP套DP,令fz[o][p1][p2]表示在[i,j]中考虑到了o这个数,最大值的位置在p1,最小值的位置在p2的方案数,那么这个DP的转移就是考虑一下o+1这个数,以及枚举子序列的间隔,间隔的代价我们已经得到了(因为[i,j]的子区间的DP值我们都已经算出了),这样fz数组也可以求出来了。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 #define maxn 55
     6 const int INF=1000000000;
     7 int dp[maxn][maxn],fz[maxn][maxn][maxn];
     8 int n,a,b,w[maxn];
     9 
    10 void getdp(int l,int r)
    11 {
    12     for (int i=l;i<=r;i++)
    13         for (int j=l;j<=i;j++)
    14             for (int k=l;k<=i;k++)
    15                 fz[i][j][k]=INF;
    16     fz[l][l][l]=0;
    17     for (int i=l;i<=r;i++) 
    18     {
    19         fz[i][i][i]=min(fz[i][i][i],dp[l][i-1]);
    20         for (int j=l;j<=i;j++)
    21             for (int k=l;k<=i;k++)
    22             {
    23                 if (fz[i][j][k]==INF) continue;
    24                 int t1= w[j]>w[i+1]?j:i+1;
    25                 int t2= w[k]<w[i+1]?k:i+1;
    26                 fz[i+1][t1][t2]=min(fz[i][j][k],fz[i+1][t1][t2]);
    27                 for (int o=i+1;o<=r;o++)
    28                     fz[o][j][k]=min(fz[o][j][k],fz[i][j][k]+dp[i+1][o]);
    29             }
    30     }
    31 }
    32 
    33 int main()
    34 {
    35     scanf("%d",&n);
    36     scanf("%d%d",&a,&b);
    37     for (int i=1;i<=n;i++) scanf("%d",&w[i]);
    38     for (int len=1;len<=n;len++)
    39         for (int l=1;l+len-1<=n;l++)
    40         {
    41             int r=l+len-1;
    42             dp[l][r]=INF;
    43             getdp(l,r);
    44             for (int i=l;i<=r;i++)
    45                 for (int j=l;j<=r;j++) 
    46                 {
    47                     if (fz[r][i][j]==INF) continue;
    48                     dp[l][r]=min(dp[l][r],fz[r][i][j]+a+b*(w[i]-w[j])*(w[i]-w[j]));
    49                 }
    50         }
    51     printf("%d
    ",dp[1][n]);
    52     return 0;
    53 }
  • 相关阅读:
    定义类或对象
    CSS 超出的文字显示省略号(单行、多行)
    获取Json对象的长度以及判断json对象是否为空
    第三次作业附加
    八皇后问题解题报告(dfs
    STL学习笔记(不定期更新)
    寒假作业之三
    寒假作业之二(2)
    寒假作业之二(1)
    第一篇随笔居然是总结耶
  • 原文地址:https://www.cnblogs.com/lvyouyw/p/6910252.html
Copyright © 2020-2023  润新知