Pangu and Stones HihoCoder - 1636 区间DP

Posted zhuyou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Pangu and Stones HihoCoder - 1636 区间DP相关的知识,希望对你有一定的参考价值。

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的主要内容,如果未能解决你的问题,请参考以下文章

[ICPC 北京 2017 J题]HihoCoder 1636 Pangu and Stones

hihoCoder 1636 Pangu and Stones

Pangu and Stones HihoCoder - 1636 区间DP

HihoCoder - 1636 Pangu and Stones(区间DP)

Hihocoder1636Pangu and Stones(区间DP)

2017北京ICPC Pangu and Stones(区间DP)