优先队列的浅谈(例题:切木棒)

题目链接:http://39.108.226.55/problem/201802287

 

Description

 

这一关兔小灰需要将一根长的木棒切成N段。每段的长度分别为L1,L2,......,LN(1 <= L1,L2,…,LN <= 1000,且均为整数)个长度单位。我们认为切割时仅在整数点处切且没有木材损失。

然而兔小灰发现,每一次切割花费的体力与该木棒的长度成正比,不妨设切割长度为1的木棒花费1单位体力。例如:若N=3,L1 = 3,L2 = 4,L3 = 5,则木棒原长为12,木匠可以有多种切法,如:先将12切成3+9.,花费12体力,再将9切成4+5,花费9体力,一共花费21体力;还可以先将12切成4+8,花费12体力,再将8切成3+5,花费8体力,一共花费20体力。显然,后者比前者更省体力。那么,兔小灰至少要花费多少体力才能完成切割任务呢?

 

Input

 

第1行:1个整数N(2 <= N <= 500)第2 - N + 1行:每行1个整数Li(1 <= Li <= 1000)。

 

Output

 

输出最小的体力消耗。

 

Sample Input 1 

3
3
4
5

Sample Output 1

19

看到了大佬的写题思路,用的优先队列,去学了一波。。在学的时候突然想到不用优先队列也可以过,模拟优先队列,

题意很明确,我们给他换一个角度解决,切不确定就接,把这些散的木棒结成一个大木棒,用的最少力气,好了,那么我们只用每次着最小的两个木棒就行了,给他结成一个大的木棒再次寻找,就解决了,这个是,n*log(n)的方法,感觉还是可以的:

ac:

#include<stdio.h>
#include<string.h>
#include<math.h>

//#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;

#define ll long long
#define da    0x3f3f3f3f
#define xiao -0x3f3f3f3f
#define clean(a,b) memset(a,b,sizeof(a))// 雷打不动的头文件

int shuzu[550];

int cmp(int a,int b)
{
	return a<b;
}

int main()
{
	int n,i,j;
	cin>>n;
	for(i=0;i<n;++i)
		cin>>shuzu[i];
	int max=n,sum=0;
	while(max>1)
	{
		sort(shuzu,shuzu+n,cmp);        //每次找最小的两个
		int a,b;
		a=shuzu[0];
		b=shuzu[1];
		sum=sum+a+b;
		shuzu[0]=b+a;                    //一个得到值
		shuzu[1]=da;                    //一个正无穷
		max--;                        //取出两个加进去一个就是取出一个的意思
	}
	cout<<sum<<endl;                        //最后输出和就行了
	
}

然后是优先队列的,上面的那个感觉还是这道题太简单,没什么其他的变量什么的,但是还是要学一下优先队列的:

优先队列的详细讲解有一个链接:http://blog.csdn.net/c20182030/article/details/70757660

注意优先队列的使用格式:


struct node{
    int first,secend;
};

struct cmp{
    bool operator()(const node &a,const node &b){
        return a.first>b.first;//这个规则是first小的排在前面
    }
};


priority_queue<node,vector<node>,cmp> que;


//-----优先队列默认的排列顺序
/*
priority_queue<int> que;
从大到小:
input:
1 2 3 4 5 6 7 8 9 
output:
9 8 7 6 5 4 3 2 1 
*/

当然,wo'm我们也可以直接定义结构体内部的排序规则,然后直接使用普通的优先队列,例:

//x大的是大的结构体
struct node{
	int x,l;
    //重载大于号
	bool operator < (const node & a)const{
		return x<a.x;
	}
};
//x是小的是大的结构体
struct node{
	int x,l;
	bool operator < (const node & a)const{
		return x>a.x;
	}
};

这样就能实现priority_queue<node> que;

的排序了

 

 

less<int> //从大到小
greater<int> //从小到大
#include<stdio.h>
#include<string.h>
#include<math.h>

//#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;

#define ll long long
#define da    0x3f3f3f3f
#define xiao -0x3f3f3f3f
#define clean(a,b) memset(a,b,sizeof(a))// 雷打不动的头文件

struct cmp{				//按照从小到大排序 
	bool operator () (int &a,int &b)
	{
		return a>b;
	}
};
int main()
{
	priority_queue<int,vector<int>,cmp/*greater<int> */> q;	//中间的这两个是一个意思 
	int n,i,j;
	cin>>n;
	for(i=0;i<n;++i)
	{
		int can;
		cin>>can;
		q.push(can);								//放入队列 
	}
	int sum=0;
	while(q.size()>1)
	{
		int a=q.top();				//输出第一小的 
		q.pop();
		int b=q.top();				//输出第二小的 
		q.pop();
		sum=sum+a+b;				//加起来 
		q.push(a+b);				//放进去 
	}
	cout<<sum<<endl;				//力气总和 
}

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值