poj3253 Fence Repair (贪心求线段分块花费最少)

ACM题集:https://blog.csdn.net/weixin_39778570/article/details/83187443
题目:http://poj.org/problem?id=3253

题意:

把一块木板切成指定的n段,一共切n-1段,每切一段的花费是木板的长度,安培切木板的顺序使得花费最少,输出最小值

题解:

类似于合并石头,这里是分木板,把一个木板长度L,分为L1,L2的花费为L
问分为指定的n断花费最小为多少。
21
13 8 分为 13 和 8 花费21
8 5 分为 8 和 5 花费13
画出这样的树,我们可以发现每次要先把最小的两个切出来,但是要切最小和次小的两个就必须要把父节点切出来,依次往上切。。。
所以问可以把切割问题转换为合并问题,把最小和次小的两个合并,成为新的子节点,计算花费,再依次往上合并直到只有一个节点
可以类别一下合并石头和poj 2054树的染色(先染父节点才能染字节点,但是我们是选择字节开始染色的,然后才去染父节点)
简而言之,就是,刀刀最小(从后往前,当前切这一刀的状态假定前面的切好了,直到一个确定的状态,就是木板一分为二的状态)

#include<iostream>
#include<cstdio>
#include<queue>
#include<vector> 
#define ll long long
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;

int n;
ll ans=0;
priority_queue<int, vector<int>, greater<int> > q;
void solve(){
	int cost;
	while(q.size()>=2){
		cost = q.top();q.pop();
		cost += q.top();q.pop();
		ans+=cost;
		q.push(cost);
	}
	cout<<ans<<endl;
}
int main(){
	scanf("%d",&n);	
	int x;
	fo(i,1,n){
		scanf("%d",&x);
		q.push(x);		
	}
	solve();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值