题目大意:
大意:需要把一根长木棍锯成一些短木棍短木棍的长度是告诉你的每一次锯的花费为要锯的改段的长度问最小花费比如n个小木棍长度分别5 8 8
也就是相当于你有一根21的木棍 现在需要把它锯成 上述的三段每次只能把一个木棍锯成两段比如21可以锯成13 和 8 但是由于选择的是21 所以花费为21
第二次把13 锯成5和8 花费 为13总花费为21 + 13 = 34
分析:其实我们可以逆向思维想在有n跟木棍现在想要把他们拼成一跟每一次的花费就是这两段的和那么我们根据贪心的思想肯定是每次选取的是最小的两段了
用堆或优先队列来写就可以了
#include <cstdio> #include <queue> #include <vector> #include <functional> //用greater时,要加上这个头文件 #include <iostream> using namespace std; int main() { int n;//需要切割的木板个数 __int64 temp, a, b, mincost; while (~scanf("%d", &n)) { //定义从小到大的优先队列,可将greater改为less,即为从大到小 priority_queue<int, vector<int>, greater<int> > Q; while (!Q.empty())//清空队列 Q.pop(); for (int i = 1; i <= n; i++) { scanf("%I64d", &temp); Q.push(temp);//输入要求的木板长度(费用)并入队 } mincost = 0;//最小费用初始为零 while (Q.size() > 1)//当队列中小于等于一个元素时跳出 { a = Q.top();//得到队首元素的值,并使其出队 Q.pop(); b = Q.top();//两次取队首,即得到最小的两个值 Q.pop(); Q.push(a + b);//把两个最小元素的和入队 mincost += a + b; } if (n == 1)mincost = temp; printf("%I64d\n", mincost); } return 0; }
2018-04-01