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)