zoukankan      html  css  js  c++  java
  • 洛谷 P1063 能量项链 & [NOIP2006提高组](区间dp,断环为链)

    传送门


    解题思路

    个人感觉难度应该在蓝题左右

    (可能是我太弱了趴)

    首先我们知道,那个所谓的头标记和尾标记,在合并区间[l...r]时,n和m是确定了的(即l的头标记和r的尾标记),只差中间的r,所以我们可以枚举k(断点)。

    然后我们又可以得出,对于合并区间[l...r],最终得分为(dp[i][k]+dp[k+1][j]+a[i][0]*a[k][1]*a[j][1]),就是左边区间的值加上右区间的值再加上合并的得分。

    对于每一个k,a[k][1]是一个定值,所以很显然,dp[i][k]和dp[k+1][j]一定要保证最大值,这也就满足了最优子结构。

    因为区间合并后,头标记和尾标记并没有任何改变,所以满足无后效性。

    所以可以放心地使用区间dp了。

    最后因为是环形,所以断环为链即可解决。

    AC代码

     1 #include<iostream>
     2 #include<algorithm>
     3 using namespace std;
     4 const int maxn=205;
     5 int n,a[maxn][2],dp[maxn][maxn],ans;
     6 int main()
     7 {
     8     cin>>n;
     9     for(int i=1;i<=n;i++){
    10         cin>>a[i][0];
    11         a[i+n][0]=a[i][0];
    12         a[i-1][1]=a[i][0];
    13         a[i+n-1][1]=a[i+n][0];
    14     }
    15     for(int len=2;len<=n;len++){
    16         for(int i=1;i<=2*n-1;i++){
    17             int j=i+len-1;
    18             if(j>2*n-1) break;
    19             for(int k=i;k<j;k++){
    20                 dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+a[i][0]*a[k][1]*a[j][1]);
    21             }
    22         }
    23     }
    24     for(int i=1;i<=n;i++){
    25         ans=max(dp[i][i+n-1],ans);
    26     }
    27     cout<<ans;
    28     return 0;
    29 }

     //NOIP2006提高组 t1

  • 相关阅读:
    十六进制转十进制
    十进制转十六进制
    历届试题 高僧斗法
    历届试题 错误票据
    历届试题 大臣的旅费
    历届试题 九宫重排/八数码问题
    Skip the Class
    历届试题 剪格子
    leetcode 337. House Robber III
    猿辅导 2019年 校招提前批笔试
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/12358788.html
Copyright © 2011-2022 走看看