UVALive 6694
来源:互联网 发布:域名劫持查询 编辑:程序博客网 时间:2024/06/04 00:54
题意:
给你n件物品,每件物品都有重量Wi,分在三个箱子里,每个箱子至少一件物品。求总费用最少(每个箱子费用=箱子总重量*箱子内物品总数)。
思路:
先按升序排序,若把物品分成总量连续的两份,以对称轴位置为x轴,费用为y轴,画出图形是一个单峰函数。高效率求单峰函数最值可以想到三分,但题目要求分成三份,所以要有两个对称轴,这时可以枚举第一个对称轴,求第二个对称轴。时间复杂度O(nlogn)。这题区间是int型的,所以可以通过mid,mid+1,求斜率来三分,效率更快。
代码:
#include <bits/stdc++.h>using namespace std;typedef long long ll;const ll INFF = 0x3f3f3f3f3f3f3f3f;const int maxn = 2e4+7;ll arr[maxn],sum[maxn];int n;ll getSum(int l,int r){ return (ll)((sum[r]-sum[l])*(r-l));}ll trisearch(int x){ int l = x+1,r = n; while(l<r-1) { int mid = (l+r)>>1; int midd = mid+1; ll td = getSum(x,mid)+getSum(mid,n); ll tdd = getSum(x,midd)+getSum(midd,n); if(td<tdd) r = mid; else l = midd; } return min(getSum(x,l)+getSum(l,n),getSum(x,r)+getSum(r,n));}int main(){ int t; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i = 1;i<=n;i++) scanf("%lld",&arr[i]); sort(arr+1,arr+n+1); ll ans = INFF; sum[0] = 0; for(int i = 1;i<=n;i++) sum[i] = sum[i-1]+arr[i]; for(int i = 1;i<=n-2;i++) ans = min(ans,sum[i]*i+trisearch(i)); printf("%lld\n",ans); } return 0;}
阅读全文
1 0
- UVALive 6694
- UVALive 6694 - 二分
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- 接口实现类方法的回调
- Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(四)调整 App.vue 和 router 路由
- char *s 和 char s[] 的区别
- 堆排序算法分析与实现
- python的numpy包中shape,tile,argsort函数与sorted函数使用方法
- UVALive 6694
- 【LeetCode】Longest Palindrome(最长回文串)
- vs2015 安装及番茄插件使用
- Gtest框架进行Windows API测试:CreateFile和枚举文件
- Java经典算法题(一)
- KFC游记——生活中的网络安全篇一
- MacOS下彻底删除多余的Python版本
- java 异常,java,异常
- 今天学习内容2017826