大致翻译:
n
个强盗去抢劫银行得到
配方案,每个人按比例 Xi/Y 分配, X1+X2+..Xn=Y , m 可能不能
被
个金币,定义不公平度为 |Xi/Y−Ki/m| ,给出了 n,m,Y,Xi ,求出
Ki ,使得不公平度的总和最小
题解:
首先,我们保证 Σ|Xi/Y−Ki/m| 最小,即 Σ|Xi∗m−Ki∗Y| 最小。
那么, dp 肯定是不行的。(可能是我太弱了…)
我们考虑先令 Ki=m∗Xi/Y ,再考虑另外的 m−ΣKi 个 1 。
因为我们由
所以 Ki 的最终值肯定为 m∗Xi/Y或m∗Xi/Y+1 。
我们再把所有的 m∗Xi/Y+1 从小到大排序,把没加的 1 <script type="math/tex" id="MathJax-Element-25">1</script>加上即可。
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 1009;
int n, m, y;
int x[MAXN];
int k[MAXN];
int sum;
int a[MAXN];
inline int iabs(int x){return x>0?x:-x;}
inline bool cmp(int a, int b)
{
int t1 = iabs(x[a]*m-(k[a]+1)*y), t2 = iabs(x[b]*m-(k[b]+1)*y);
return t1 < t2 || (t1 == t2 && a > b);
}
int main()
{
scanf("%d%d%d", &n, &m, &y);
for(int i = 1; i <= n; ++i)
{
scanf("%d", x+i);
k[i] = m*x[i]/y;
sum += k[i];
a[i] = i;
}
sort(a+1, a+n+1, cmp);
for(int i = 1; i <= m-sum; ++i) k[a[i]]++;
for(int i = 1; i <= n; ++i)
printf("%d ", k[i]);
return 0;
}