一位老木匠需要将一根长的木棒切成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 <= 50000) 第2 - N + 1行:每行1个整数Li(1 <= Li <= 1000)。 Output
输出最小的体力消耗。 Sample Input
3
3
4
5 Sample Output
19
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <math.h>
#include <bitset>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include<functional>
#include<time.h>
#include<stdlib.h>
#include<time.h>
#include <climits>
using namespace std;
#define MEM(a,x) memset(a,x,sizeof(a))
#define gcd(a,b) __gcd(a,b)
#define ll long long
#define EXP 1e-8
#define lowbit(x) (x&-x)
#define debug(x) cout<<x<<' ';
const int maxn = 1e6;
int dp[30][maxn];
int a[maxn];
int main()
{
int n;
priority_queue<int, vector<int>, greater<int> >q;
cin >> n;
int sum = 0;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
q.push(a[i]);
}
int ans = 0;
for (int i = 1; i < n; i++)
{
int p = 0;
ans += q.top();
p += q.top();
q.pop();
ans += q.top();
p += q.top();
q.pop();
q.push(p);
}
//cout << ans << endl;
cout << ans << endl;
return 0;
}
本文探讨了一个关于木匠如何以最少体力切割木棒的问题,给出了一个利用优先队列实现的算法,通过计算每一步的体力消耗找到最节省方案。
1万+

被折叠的 条评论
为什么被折叠?



