传送门:http://codeforces.com/contest/967/problem/D
题目大意:
有两个任务分别需要x1,x2的资源,现在有n台服务器,分别提供si的资源。现在将这n台服务器分配给这两个任务(可以不分完),设分给第一个k1台,第二个k2台,需要满足对于每个分配给任务1的服务器,都有si>=x1/k1;任务2同理。求能否分配,如果能分配,则输出分配的方法。
思路:
先将提供的资源排序。然后从最小的开始搜,枚举分给任务1的数量n1=x1/si,如果n1大于n则接着搜,否则枚举分给任务2的数量n2=x2/s(i+n1),如果i+n1+n2<=n则找到分配方法输出答案,否则接着搜。
另外可能存在需要先分配给任务2再分配给任务1的情况,因此还需要再搜一次,先枚举任务2的数量再枚举任务1的数量。
AC代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cstdlib> #include<utility> #include<algorithm> #include<utility> #include<queue> #include<vector> #include<set> #include<stack> #include<cmath> #include<map> #define P pair<int,int> #define ll long long #define INF 1e10 #define M 1e9+7 #define MAX 500010 #define lson id*2,l,mid #define rson id*2+1,mid+1,r using namespace std; struct node { int no; ll num; }; ll n, x1, x2; node a[300010]; bool cmp(node a, node b) { return a.num < b.num; } int main() { cin >> n >> x1 >> x2; for (int i = 0; i < n; i++) { cin >> a[i].num; a[i].no = i + 1; } sort(a, a + n, cmp); int num1, num2; for (int i = 0; i < n; i++) { num1 = x1 / a[i].num; if (x1%a[i].num != 0) num1++; if (i + num1 >= n) continue; num2 = x2 / a[i + num1].num; if (x2%a[i + num1].num != 0) num2++; if (i + num1 + num2 > n) continue; cout << "Yes" << endl; cout << num1 << ' ' << num2 << endl; for (int j = 0; j < num1; j++) cout << a[i++].no << ' '; cout << endl; for (int j = 0; j < num2; j++) cout << a[i++].no << ' '; cout << endl; return 0; } for (int i = 0; i < n; i++) { num1 = x2 / a[i].num; if (x2%a[i].num != 0) num1++; if (i + num1 >= n) continue; num2 = x1 / a[i + num1].num; if (x1%a[i + num1].num != 0) num2++; if (i + num1 + num2 > n) continue; cout << "Yes" << endl; cout << num2 << ' ' << num1 << endl; for (int j = 0; j < num2; j++) cout << a[n - 1 - j].no << ' '; cout << endl; for (int j = 0; j < num1; j++) cout << a[n - 1 - num2 - j].no << ' '; cout << endl; return 0; } cout << "No" << endl; return 0; }