【贪心+二分】codeforces C. Sagheer and Nubian Market
2024-09-30 07:33:50
http://codeforces.com/contest/812/problem/C
【题意】
如何花最少的钱买最多的纪念品?首要满足纪念品尽可能多,纪念品数量一样花钱要最少,输出纪念品数量以及最少花费。
纪念品的价钱是这么定义的:,其中a是基价,k是总共要买的纪念品数量,x是纪念品的index。
题目给出各个纪念品的基价a(当然,x也随之确定)
【思路】
二分纪念品数量,判断是否满足题意直接贪心,O(n)算出每个纪念品的价钱,O(nlogn)排序,选出最小的mid个;
二分时间复杂度O(n).
所以总的时间复杂度是O(nlogn^2),1000 00刚好满足
【Accepted】
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <vector>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <bitset>
#include <ctime>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1e5+;
struct souv
{
int base;
int x;
}a[maxn];
int n,S;
typedef long long ll;
int judge(int mid)
{
ll b[maxn];
for(int i=;i<=n;i++)
{
b[i]=(ll)a[i].base+(ll)a[i].x*(ll)mid;
}
sort(b+,b+n+);
ll sum=;
for(int i=;i<=mid;i++)
{
sum+=b[i];
}
if(sum<=(ll)S)
{
return sum;
}
return -; }
int main()
{
while(~scanf("%d%d",&n,&S))
{
for(int i=;i<=n;i++)
{
scanf("%d",&a[i].base);
a[i].x=i;
}
int l=;
int r=n;
int res=S;
while(l<=r)
{
int mid=(l+r)>>;
int ans=judge(mid);
if(ans!=-)
{
res=ans;
l=mid+;
}
else
{
r=mid-;
}
}
cout<<r<<" "<<res<<endl;
}
return ;
}
二分
最新文章
- PHP二维数组排序(list_order)
- C语言实现栈
- 短视频APP+不同类型社交应用发展分析+化妆品电商
- offsetLeft和style.left的区别
- WCF初探-15:WCF操作协定
- S2--《深入.NET平台和C#编程》
- 使用jquery获取url及url参数的方法及定义JQuery扩展方法
- cocos2d 单点触控
- sql order by+字段,指定按照哪个字段来排序
- Swing做的非阻塞式仿飞秋聊天程序
- oracle作业
- Android工具包
- 【mongoDB中级篇①】游标cursor
- 解决eclipse 使用run运行,始终会跳到debug模式!
- 关注LoadRunner脚本回放日志中的Warning信息-转载
- tableview 重用nib cell
- hdoj 2063 过山车 【双边匹配匈牙利算法】
- 封装redis
- SQLServer约束介绍
- http请求参数中文乱码的问题