注 意 到 有 些 糖 果 太 贵 , 我 们 不 可 能 买 得 起 注意到有些糖果太贵,我们不可能买得起 注意到有些糖果太贵,我们不可能买得起

不 妨 开 一 个 数 组 按 照 糖 果 从 大 到 小 排 序 , 统 计 当 前 的 糖 果 价 值 和 s u m n 不妨开一个数组按照糖果从大到小排序,统计当前的糖果价值和sumn 不妨开一个数组按照糖果从大到小排序,统计当前的糖果价值和sumn

第 一 次 遍 历 , 剔 除 掉 那 些 根 本 买 不 起 的 糖 果 , 得 到 新 的 s u m n 第一次遍历,剔除掉那些根本买不起的糖果,得到新的sumn 第一次遍历,剔除掉那些根本买不起的糖果,得到新的sumn

那 么 可 以 完 整 得 买 这 些 糖 果 m / s u m n 次 , 加 到 答 案 上 去 , m 还 剩 n % s u m n 那么可以完整得买这些糖果m/sumn次,加到答案上去,m还剩n\%sumn 那么可以完整得买这些糖果m/sumn次,加到答案上去,m还剩n%sumn

然 后 再 从 1 循 环 到 n , 硬 模 拟 买 掉 部 分 能 买 得 起 的 糖 果 然后再从1循环到n,硬模拟买掉部分能买得起的糖果 然后再从1循环到n,硬模拟买掉部分能买得起的糖果

下 一 次 遍 历 , 再 剔 除 掉 那 些 不 可 能 买 得 起 的 糖 果 , 重 复 上 面 的 步 骤 下一次遍历,再剔除掉那些不可能买得起的糖果,重复上面的步骤 下一次遍历,再剔除掉那些不可能买得起的糖果,重复上面的步骤

虽然看起来每次遍历都需要O(n)得复杂度,但是因为每次都会剔除糖果

时间复杂度完全ok

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
ll n,m,a[maxn],sumn,ans,s[maxn];
bool com(ll a,ll b){ return a>b; }
int main()
{
cin >> n >> m;
for(int i=1;i<=n;i++)
{
cin >> a[i];
sumn+=a[i];
s[i]=a[i];
}
sort(s+1,s+1+n,com);
ll top=1,shu=n;
while(1)
{
for(int i=top;i<=n;i++)
{
if(m>=s[i]) break;//只要能选就行
top++,shu--,sumn-=s[i];
}
if(sumn==0||top==n+1) break;
if(m>=sumn)//能全部全掉就全部选
{
ans+=m/sumn*shu;
m%=sumn;
}
for(int i=1;i<=n;i++)//这里可以用树状数组二分来优化
{
if(m<a[i]) continue;
m-=a[i],ans++;
}
}
cout<<ans;
}