zoukankan      html  css  js  c++  java
  • Pangu and Stones HihoCoder

    Pangu and Stones HihoCoder - 1636

    题意

    给你(n)堆石子,每次只能合成(x)堆石子((xin[L, R])),问把所有石子合成一堆的最小花费。

    思路

    和合石子的那题很像,多加了的一个限制,所有我们可以想到要多开一维数组来计算。
    (dp[i][j][x]:)表示区间([i, j])的范围内有(x)堆石子。
    然后我们要分成两类讨论((sum[i])表示前(i)堆石子的和)
    (1)(dp[i][j][1] = min(dp[i][j][x] + sum[j]-sum[i-1], dp[i][j][1]) xin[L, R])
    (x)堆合并成一堆
    (2)(dp[i][j][x] =min(dp[i][k][1]+d[k+1][j][x-1], dp[i][j][x]) xin[2, min(j-i+1, R)])
    算区间([i, j])里有(x)堆石子的最小花费

    (练习赛的时候,思路大方向没错,但是区间DP完全写错,怎么也写不出来正解。。。在被队友打死的边缘试探)

    代码

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #define mes(a, b) memset(a, b, sizeof a)
    using namespace std;
    typedef long long ll;
    const int maxn = 1e2+10;
    const ll inf = 1e17;
    ll dp[maxn][maxn][maxn];
    ll sum[maxn];
    int main(){
        int n, l, r;
        while(scanf("%d%d%d", &n, &l, &r) !=EOF){
            sum[0] = 0;
            for(int i = 1; i <= n; i++){
                scanf("%lld", &sum[i]);
                sum[i] += sum[i-1];
            }
            for(int i = 1; i <= n; i++){
                for(int j = i; j <= n; j++){
                    for(int k = 1; k <= j-i+1; k++){
                        dp[i][j][k] = inf;
                    }
                    dp[i][j][(j-i+1)] = 0;
                }
            }
            for(int len = 2; len <= n; len++){  //枚举长度
                for(int i = 1; i+len-1 <= n; i++){  //枚举左端点
                    int j = i+len-1;  //根据长度和左端点,得出右端点
                    for(int x = 2; x <= min(len, r); x++){  //枚举区间石子堆数
                        for(int k = i; k < j && k <= j-x+1; k++){  //枚举中间断点
                        // j-(k+1)+1>=x-1  =>  k <= j-x+1, 区间石子数不能大于区间长度
                            dp[i][j][x] = min(dp[i][j][x], dp[i][k][1]+dp[k+1][j][x-1]);
                        }
                        if(x >= l)
                            dp[i][j][1] = min(dp[i][j][1], dp[i][j][x]+sum[j]-sum[i-1]);
                    }
                }
            }
            if(dp[1][n][1] >= inf)
                printf("0
    ");
            else
                printf("%lld
    ", dp[1][n][1]);
        }
        return 0;
    }
    
    
  • 相关阅读:
    10.30 afternoon
    10.29 afternoon
    10.29 morning

    10.27 noip模拟试题
    codevs 3052 多米诺 二分图匹配
    poj 1849 Two
    10.26 noip模拟试题
    10.25 noip模拟试题
    .NET Core EF 版本问题
  • 原文地址:https://www.cnblogs.com/zhuyou/p/11565078.html
Copyright © 2011-2022 走看看