码迷,mamicode.com
首页 > 其他好文 > 详细

Pangu and Stones HihoCoder - 1636 区间DP

时间:2019-09-21 23:35:09      阅读:82      评论:0      收藏:0      [点我收藏+]

标签:min   cst   --   define   and   eof   string   数组   one   

Pangu and Stones HihoCoder - 1636

题意

给你\(n\)堆石子,每次只能合成\(x\)堆石子\((x\in[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]) \ \ x\in[L, R]\)
\(x\)堆合并成一堆
\(2\)\(dp[i][j][x] =min(dp[i][k][1]+d[k+1][j][x-1], dp[i][j][x]) \ \ x\in[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\n");
        else
            printf("%lld\n", dp[1][n][1]);
    }
    return 0;
}

Pangu and Stones HihoCoder - 1636 区间DP

标签:min   cst   --   define   and   eof   string   数组   one   

原文地址:https://www.cnblogs.com/zhuyou/p/11565078.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!