哈夫曼树
合并果子
每次合并堆中权值最小两个点,直到得到完整的哈夫曼树,证明略
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
int n;
int main(){
cin>>n;
priority_queue<int,vector<int>,greater<int>> heap;
for(int i=0;i<n;i++){
int w;
cin>>w;
heap.push(w);
}
int res=0;
while(heap.size()>1){
int a=heap.top();
heap.pop();
int b=heap.top();
heap.pop();
heap.push(a+b);
res+=a+b;
}
cout<<res;
}
排序不等式
排队打水
短进程优先,现将所有等待时间从小到大排序即是等待时间最优解
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int s[N],a[N];
int main(){
int n;
cin>>n;
long long res=0;
for(int i=1;i<=n;i++)cin>>a[i];
sort(a+1,a+n+1);
for(int i=1;i<=n;i++){
s[i]=s[i-1]+a[i];
res+=s[i-1];
}
cout<<res;
}
绝对值不等式
货仓选址
假设坐标为
x1,x2...xn-1,xn
(n为偶数时,将其两两分组),得到distance=abs(xn-x1)+abs(xn-1-x2).....+abs(x (n+1)/2 -x(n-1)/2 )
.
显然可以得出,当x区在中间位置时,可得总和最小值,n为奇数时去得xn/2即可
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int a[N];
int main(){
int n;
cin>>n;
int res=0;
for(int i=0;i<n;i++)cin>>a[i];
sort(a,a+n); //首先将各点按照坐标从大到小存放
for(int i=0;i<n;i++)res+=abs(a[i]-a[n/2]);
cout<<res;
}
推公式
耍杂技的牛
假设存在一序列
N1,N2.......Ni1,Ni+1,....
现考量第i
头牛和第i+1
头牛之间风险系数的关系
- 当前两头牛的风险值分别为 N i = W 1 + W 2 + . . . W i − 1 − S i \ N_{i}=W_1+W_2+...W_{i-1}-S_i Ni=W1+W2+...Wi−1−Si
N i + 1 = W 1 + W 2 + . . . W i − 1 + W i − S i + 1 \ N_{i+1}=W_1+W_2+...W_{i-1}+W_{i}-S_{i+1} Ni+1=W1+W2+...Wi−1+Wi−Si+1- 调换两头牛位置之后风险值分别为 N i = W 1 + W 2 + . . . W i − 1 + W i + 1 − S i \ N_{i}=W_1+W_2+...W_{i-1}+W_{i+1}-S_{i} Ni=W1+W2+...Wi−1+Wi+1−Si
N i + 1 = W 1 + W 2 + . . . W i − 1 − S i + 1 \ N_{i+1}=W_1+W_2+...W_{i-1}-S_{i+1} Ni+1=W1+W2+...Wi−1−Si+1- 去掉公共部分得到交换前后的风险值分别为
- 交换前: N i = − S i \ N_{i}=-S_i Ni=−Si, N i + 1 = W i − S i + 1 \ N_{i+1}=W_{i}-S_{i+1} Ni+1=Wi−Si+1
- 交换后: N i = W i + 1 − S i \ N_{i}=W_{i+1}-S_{i} Ni=Wi+1−Si
N i + 1 = − S i + 1 \ N_{i+1}=-S_{i+1} Ni+1=−Si+1
- 显而易见,交换前后的风险值最大值
显然应该在交换前的Ni+1和交换后的Ni中选取
:- 倘若满足
Ni+1>Ni
,即得到 W i + S i > W i + 1 + S i + 1 \ W_i+S_i>W_{i+1}+S_{i+1} Wi+Si>Wi+1+Si+1
则交换之后可以降低最大风险值大小
- 由此得出,只要将体重和强壮之和小的牛排在上面即可
#include<iostream>
#include<algorithm>
using namespace std;
const int N=50010;
typedef pair<int,int> PII;
PII cows[N];
int n;
int main(){
cin>>n;
for(int i=0;i<n;i++){
int w,s;
cin>>w>>s;
cows[i]={w+s,w};
}
sort(cows,cows+n); //按照w+s从小到大排序
int sum=0,res=-2e9; //初始化重量和,以及风险最大值
for(int i=0;i<n;i++){
int s=cows[i].first-cows[i].second,w=cows[i].second;
res=max(res,sum-s);
sum+=w;
}
cout<<res;
}