跳到主要内容

题解:P11462 huaijiao 要加学

· 阅读需 1 分钟
lailai
Blogger

原题链接

解题思路

W=i=1n(wi×ci)=i=1n(min(1,xiki)×100×ci)=100i=1n(min(ki,xi)×ciki)\begin{aligned} W &= \sum_{i=1}^n(w_i\times c_i) \\ &= \sum_{i=1}^n\left(\min\left(1,\frac{x_i}{k_i}\right)\times 100\times c_i\right) \\ &= 100\sum_{i=1}^n\left(\min(k_i,x_i )\times \frac{c_i}{k_i}\right) \end{aligned}

可以发现,第 ii 门课程每学一天的收益是 ciki\frac{c_i}{k_i},且最多可学 kik_i 天。为了最大化总收益,应优先选择收益较高的课程。

因此,可以按 ciki\frac{c_i}{k_i} 从大到小排序,然后贪心地选择每门课程最多学习 x=min(ki,m)x = \min(k_i, m) 天,并更新剩余天数 mmxm \gets m - x

参考代码

#include <bits/stdc++.h>
using namespace std;

using ll=long long;
const int N=1005;
struct Node
{
int c,k;
}a[N];
bool cmp(const Node &u,const Node &v)
{
return u.c*v.k>v.c*u.k;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i].c;
for(int i=1;i<=n;i++)cin>>a[i].k;
sort(a+1,a+n+1,cmp);
double ans=0;
for(int i=1;i<=n;i++)
{
int x=min(m,a[i].k);
ans+=x*100.0/a[i].k*a[i].c;
m-=x;
}
cout<<fixed<<setprecision(4)<<ans<<'\n';
return 0;
}