从oj上看到一道问题,合并果子,题意如下:
1171.合并果子
Time Limit: 1000 MS Memory Limit: 32768 KB
Total Submission(s): 77 Accepted Submission(s): 18
Description
在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。
每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。
因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。
例如有3种果子,数目依次为1,2,9。可以先将1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。所以多多总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。
Input
输入包括两行,第一行是一个整数n(1<=n<=10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1<=ai<=20000)是第i种果子的数目。
Output
输出包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于231。
Sample Input
3
1 2 9
Sample Output
15
乍一看感觉很简单,无非是把所有数据按升序排列然后进行简单加和运算,但是wa
后来发现其实问题在于合并之后的数不一定是最小的数,所以每次合并之后都要进行重新排序,然后必定会超时。。。
本来以为是一道水题,搜了搜题解,好像是关于优先队列的(选择排序也能做出来),正好搜了搜关于优先队列的知识,优先队列的排序,应用一下。
先挂代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<cmath>
using namespace std;
struct cmp
{
int m;
friend bool operator < (cmp a, cmp b) {
return a.m > b.m;
}
};
int main()
{
priority_queue<cmp>ans;
cmp a,b;
int n, sum = 0;
cin>>n;
for(int i = 0; i < n; i ++)
{
cin>>a.m;
ans.push(a);
}
for(int i = 0; i < n - 1; i ++)
{
a = ans.top(),ans.pop();
b = ans.top(),ans.pop();
sum += a.m + b.m;
a.m += b.m;
ans.push(a);
}
cout<<sum<<endl;
return 0;
}
每次都把最小的定位优先级高的
这样就不用每次排序,问题迎刃而解
看了很多大神都是把优先队列排序放在结构体里进行,也很方便
这里说两种我用着顺手的排序方式
①:
struct cmp
{
int m;
friend bool operator < (cmp a, cmp b) {
return a.m > b.m;
}
};//从小到大排列 (用 > 表示从小到大)
看到大神说②和这个是一样的
②:
struct cmp{
int x,y;
};
bool operator(const cmp &a,const cmp &b)
{
return a.x>b.x;
};
priority_queue<cmp>ans;
①和②都是对结构体进行重载操作符
③没找到他的名字,但是也是ac的代码
③:
struct cmp
{
int m;
bool operator < (const cmp &d)
const
{
return d.m < m;
}
};//同为从小到大排列
还有④自定义优先级
④:
struct cmp{
bool operator()(int a,int b)
{
return a>b; //x小的优先级高。
}
};
priority_queue<int,vector<int>,cmp>ans;
所以学会了吗,你?
然后再来一道题,看到有一道题和这个一样的
1501.Problem_J
Time Limit: 2000 MS Memory Limit: 32768 KB
Total Submission(s): 78 Accepted Submission(s): 28
Description
So long coding time make ChaoChao be more nonsense. In order to spend the boring time, ChaoChao plan to practice his cooking stills.
Now, CC wants to make N foods. The i-th food need a[i] unit meat, but CC find that there is only a whole meat and he need to consume energy to cut meat. Consumption value is equal to the size of the cut meat. For example, there is a 21 units meat, so CC will consume 21 energy to cut it. CC wants to cut meat into N small meat. He wants to know the minimum number of the energy he need.(The size of the meat bought is equal to the sum of N pieces of meat.)
INPUT
The first line is a number N (1 ≤ N ≤ 20000) identified the number of small meat.
Then next N lines, each line contains one number a[i](1 ≤ a[i] ≤ 50000) means a[i] units of the i-th meat.
Input
The first line is a number N (1 ≤ N ≤ 20000) identified the number of small meat.
Then next N lines, each line contains one number a[i](1 ≤ a[i] ≤ 50000) means a[i] units of the i-th meat.
Output
The minimum number of the energy.
Sample Input
3
8
5
8
Sample Output
34
连蒙带猜可以读懂题意,其实就是合并果子,用近乎一样的代码ac了
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<cmath>
using namespace std;
struct cmp
{
long long m;
friend bool operator < (cmp a, cmp b) {
return a.m > b.m;
}
};
int main()
{
priority_queue<cmp>ans;
cmp a,b;
long long n, sum = 0;
while(scanf("%lld",&n)!=EOF){
sum = 0;
for(long long i = 0; i < n; i ++)
{
cin>>a.m;
ans.push(a);
}
for(long long i = 0; i < n - 1; i ++)
{
a = ans.top(),ans.pop();
b = ans.top(),ans.pop();
sum += a.m + b.m;
a.m += b.m;
ans.push(a);
}
cout<<sum<<endl;
while(!ans.empty())
ans.pop();
}
return 0;
}
sdnuoj1412.Huffuman树用一样的代码也是能ac,,怎么那么多一样的题啊,这oj是水。。。
其实就是一样,把同类题归总一下有空看看
另 队列不能直接清空,搜了搜队列清空方式,多次调用队列时会用到
//方法一,遍历出队列
priority_queue<int>q;
while(!q.empty())
q.pop();
//方法二,用空的队列对象赋值
q = priority_queue<int>();
//方法三,使用swap定义空数组(效率最高)
void clear(priority_queue<int> &q)
{
priority_queue<int>empty;
swap(empty,q);
}