训练赛第二场G题 ZOJ 2343
2013-09-05 21:40
295 查看
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2343
解题报告:首先我假设最后的正确的结果是a[1] , a[2] ,a[3] ....a[i];然后我们先把这M个金币完全按照x[i] / Y的比例先预分配一下,分配的同时,统计出分配结束后还会剩余多少个金币,假设第一轮分配之后每个人得到的金币数量分别是k[1],k[2],......k[i],那么可以确定的是
a[i] - k[i] 是等于0或者等于1的,也就是说如果有些人的当前拿到的金币数量并不是符合最后的结果的话,那么这个人当前拿到的金币最多只比他应该得到的金币的数量少了一个,于是我们现在就可以将剩余的这left个金币分配给所有还少拿了一个金币的人,那么到底应该分给谁呢?
很显然,应该分给那个x[i]/Y - k[i]/M最大 的人,因为当分给这个人之后这个人的x[i]/Y - k[i]/M的值一定会变小,这样就可以达到总的值最小的目的。
View Code
解题报告:首先我假设最后的正确的结果是a[1] , a[2] ,a[3] ....a[i];然后我们先把这M个金币完全按照x[i] / Y的比例先预分配一下,分配的同时,统计出分配结束后还会剩余多少个金币,假设第一轮分配之后每个人得到的金币数量分别是k[1],k[2],......k[i],那么可以确定的是
a[i] - k[i] 是等于0或者等于1的,也就是说如果有些人的当前拿到的金币数量并不是符合最后的结果的话,那么这个人当前拿到的金币最多只比他应该得到的金币的数量少了一个,于是我们现在就可以将剩余的这left个金币分配给所有还少拿了一个金币的人,那么到底应该分给谁呢?
很显然,应该分给那个x[i]/Y - k[i]/M最大 的人,因为当分给这个人之后这个人的x[i]/Y - k[i]/M的值一定会变小,这样就可以达到总的值最小的目的。
#include<cstdio> double Y,x[1005]; int N,M,k[1005]; int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d%lf",&N,&M,&Y); for(int i = 0;i < N ;++i) scanf("%lf",&x[i]); int left = M; for(int i = 0;i<N;++i) { k[i] = 1.0 * ( x[i] / Y ) * M; left -= k[i]; } while(left) { int l = 0; for(int i = 0 ;i < N;++i) if(1.0*(double)x[i]/Y-(double)k[i]/(double)M >= 1.0*(double)x[l]/Y-(double)k[l]/(double)M) l = i; k[l]++; left--; } for(int i = 0;i < N;++i) printf(i == 0? "%d":" %d",k[i]); puts(""); } return 0; }
View Code
相关文章推荐
- 训练赛第二场C题 zoj 2339 Hyperhuffman
- zoj 2343 Robbers 尽量按比例分配 (4-G)
- 2013暑假集训B组训练赛第二场 - A Bus Game
- ZOJ 2343 Robbers(思路)
- zoj 2343 Robbers (G)
- 2013暑假集训B组训练赛第二场 - E Queue at the School
- ZOJ 2343 Robbers(思路)
- zoj 2343 Robbers 尽量按比例分配 (4-G)
- ZOJ 2343 Robbers(思路)
- zoj 2343 Robbers 尽量按比例分配 (4-G)
- 2013暑假集训B组训练赛第二场 - B - Funky Numbers
- ZOJ 2343 Robbers(思路)
- ZOJ 2343 Robbers(思路)
- ZOJ 2343 Robbers(思路)
- ZOJ 2343 Robbers(思路)
- ZOJ 2343 Robbers(思路)
- 哈理工2015 暑假训练赛 zoj 2976 Light Bulbs
- 训练赛第二场E题 Cottage Village
- ZOJ2343 Robbers(贪心)
- 哈理工2015暑假训练赛 zoj 2078Phone Cell