Pangu and Stones HihoCoder - 1636 (区间DP) 2017区域赛北京站

Pangu and Stones

 题目链接:HihoCoder - 1636 

题意:现有n堆石子,每次合并k堆石子,L<=k<=R,每次合并石子花费代价是合并的石子的总数量;问最后能否合并成一堆石子,若能,输出最小代价;反之输出0;

思路:令dp[i][j][k]表示将区间[i, j]合并成k堆所花费最小代价;

当k=1时,dp[i][j][1]=min(dp[i][i+x][k-1]+dp[i+x+1][j][1]+sum[i][j]  |  i<=x<=j,   L<=k<=R);

当k>=2时, dp[i][j][k]=min(dp[i][i+x][k-1]+dp[i+x+1][j][1]   |   i<=x<=j);

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
int sum[110][110], dp[110][110][110], a[110];
int main(){
	int N, L, R;
	while(~scanf("%d%d%d", &N, &L, &R)){
		memset(dp, INF, sizeof(dp));			
		for(int i=1; i<=N; i++){
			scanf("%d", &a[i]);
		}
		for(int i=1; i<=N; i++){
			sum[i][i-1]=0;
			for(int j=i; j<=N; j++){
				sum[i][j]=sum[i][j-1]+a[j];
				dp[i][j][j-i+1]=0;
			}
		}
		for(int d=1; d<=N; d++){
			for(int i=1; i+d<=N; i++){
				for(int j=i; j<i+d; j++){
					for(int k=L-1; k<=R-1; k++){
						dp[i][i+d][1]=min(dp[i][i+d][1], dp[i][j][k]+dp[j+1][i+d][1]+sum[i][i+d]);
					}
				}
				for(int k=2; k<=d; k++){
					for(int j=i; j<i+d; j++){
						dp[i][i+d][k]=min(dp[i][i+d][k], dp[i][j][k-1]+dp[j+1][i+d][1]);
					}
				}
			}
		}
		if(dp[1][N][1]==INF) printf("0\n");
		else printf("%d\n", dp[1][N][1]);
	}
	return 0;
} 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值