P1414 又是毕业季II
题目描述
彩排了一次,老师不太满意。当然啦,取每位同学的号数来找最大公约数显然不太合理。于是老师给每位同学评了一个能力值。于是现在问题变为,从n个学生中挑出k个人使得他们的默契程度(即能力值的最大公约数)最大。但因为节目太多了,而且每个节目需要的人数又不知道。老师想要知道所有情况下能达到的最大默契程度是多少。这下子更麻烦了,还是交给你吧~
PS:一个数的最大公约数即本身。
输入输出格式
输入格式:
第一行一个正整数n。
第二行为n个空格隔开的正整数,表示每个学生的能力值。
输出格式:
总共n行,第i行为k=i情况下的最大默契程度。
输入输出样例
说明
【题目来源】
lzn原创
【数据范围】
记输入数据中能力值的最大值为inf。
对于20%的数据,n<=5,inf<=1000
对于另30%的数据,n<=100,inf<=10
对于100%的数据,n<=10000,inf<=1e6
贪心:k越大,最大公约数越小
暴力枚举:从最大项向下枚举至1
#include <bits/stdc++.h> using namespace std; #define maxn 1000005 typedef long long ll; #define inf 2147483647 #define ri register int int n; int cnt[maxn]; int top; int r; int ans[maxn]; int check(int x) { if (ans[x]) return ans[x]; int y = x; int sum = 0; while (y <= r) { sum += cnt[y]; y += x; } return ans[x] = sum; } int main() { ios::sync_with_stdio(false); freopen("test.txt", "r", stdin); // freopen("outout.txt","w",stdout); cin >> n; for (int i = 1; i <= n; i++) { int t; cin >> t; cnt[t]++; r = max(r, t); } top = r; for (int i = 1; i <= n; i++) { while (top > 1 && check(top) < i) top--; cout << top << endl; } return 0; }