zoukankan      html  css  js  c++  java
  • HDU 3506 Monkey Party(区间DP)题解

    题意:有n个石堆排成环,每次能合并相邻的两堆石头变成新石堆,代价为新石堆石子数,问最少的总代价是多少

    思路:先看没排成环之前怎么做:用dp[i][j]表示合并i到j所需的最小代价,那么dp[i][j]就是合并i~k、k+1~j的最小代价,即dp[i][j] = min(dp[i][j],dp[i][k] + dp[k + 1][j] + w[i][j]])。 

    for(int len = 1; len <= n; len++){  //区间长度
      for(int i = 1; i + len - 1 <= n; i++){  //起始位置
        int j = i + len - 1;  //末尾位置
        for(int k = i; k <= j; k++){
             if(dp[i][j] > dp[i][k] + dp[k + 1][j] + w[i][j]){
                dp[i][j] = dp[i][k] + dp[k + 1][j] + w[i][j]];
               }
           }
        }
    }

    合并石堆环是,只要把n首尾相接扩展到2n,就可以了。

    这个dp还可以用四边形不等式优化

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    typedef long long ll;
    using namespace std;
    const int maxn = 1000 + 10;
    const int MOD = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    int a[maxn], dp[maxn << 1][maxn << 1], sum[maxn];
    int s[maxn << 1][maxn << 1];  //i到j的最佳分割点
    int main(){
        int n;
        while(~scanf("%d", &n)){
            sum[0] = 0;
            memset(dp, INF, sizeof(dp));
            for(int i = 1; i <= n; i++){
                scanf("%d", &a[i]);
                a[i + n] = a[i];
            }
            for(int i = 1; i <= 2 * n; i++){
                s[i][i] = i;
                dp[i][i] = 0;
                sum[i] = sum[i - 1] + a[i];
            }
            for(int len = 1; len <= n; len++){  //长度
                for(int i = 1; i + len - 1 <= 2 * n; i++){  //起始位置
                    int j = i + len - 1;
                    for(int k = s[i][j - 1]; k <= s[i + 1][j]; k++){
                        if(dp[i][j] > dp[i][k] + dp[k + 1][j] + sum[j] - sum[i - 1]){
                            dp[i][j] = dp[i][k] + dp[k + 1][j] + sum[j] - sum[i - 1];
                            s[i][j] = k;
                        }
                    }
                }
            }
            int ans = INF;
            for(int i = 1; i <= n; i++){
                ans = min(ans, dp[i][i + n - 1]);
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    构建智慧城市的五个关键点
    构建智慧城市的五个关键点
    构建智慧城市的五个关键点
    构建智慧城市的五个关键点
    微软Project Online落地中国
    微软Project Online落地中国
    微软Project Online落地中国
    微软Project Online落地中国
    美团容器平台架构及容器技术实践
    Python爬虫入门教程 30-100 高考派大学数据抓取 scrapy
  • 原文地址:https://www.cnblogs.com/KirinSB/p/10306087.html
Copyright © 2011-2022 走看看