http://codeforces.com/contest/967/problem/D
题目大意:
有n个服务器,标号为1~n,每个服务器有C[i]个资源。现在,有两个任务需要同时进行,令他为x1,x2.
运行任务的条件:
①每个服务器只能同时运行一个任务
②任务可以同时分配到多个服务器中执行。假设任务x1分配到a个服务器中,则每个服务器都需要使用x1/a的资源(该资源可以为小数)
问能否满足以上条件,使得x1,x2同时在服务器中运行?
思路:
将所有服务器按照资源增序排列,定义dp(i)表示从第i个服务器到第n个服务器的资源提供量, 即dp[i] = (n - i + 1) * c[i];
接下来,暴力一遍1~n,
在满足dp(i)>=x1的时候,就贪心的取最少的满足c(i) * cnt >= x1
然后再利用dp去找满足x2的条件即可。
//看看会不会爆int!数组会不会少了一维! //取物问题一定要小心先手胜利的条件 #include <bits/stdc++.h> using namespace std; #pragma comment(linker,"/STACK:102400000,102400000") #define LL long long #define ALL(a) a.begin(), a.end() #define pb push_back #define mk make_pair #define fi first #define se second #define haha printf("haha ") const int maxn = 1e6 + 5; int n, x1,x2; vector<pair<int, int> > ve; int dp[maxn]; pair<int, int> ans1, ans2; bool check(int i, int x1, int x2){ int cnt1 = x1 / ve[i].fi; if (x1 - cnt1 * ve[i].fi > 0) cnt1++; if (dp[i + cnt1] >= x2) { ans1 = mk(i, i + cnt1 - 1); ans2.fi = i + cnt1; int cnt2 = x2 / ve[i+cnt1].fi; if (x2 - cnt2 * ve[i+cnt1].fi > 0) cnt2++; ans2.se = ans2.fi + cnt2 - 1; return true; } return false; } bool solve(){ bool flag = false; for (int i = 0; i < ve.size(); i++){ if (dp[i] >= x1){ if (check(i, x1, x2)) flag = true; } } if (flag == false){ swap(x1, x2); for (int i = 0; i < ve.size(); i++){ if (dp[i] >= x1){ if (check(i, x1, x2)) { flag = true; swap(ans1, ans2); } } } } if (flag){ puts("Yes"); printf("%d %d ", ans1.se - ans1.fi + 1, ans2.se - ans2.fi + 1); for (int j = ans1.fi; j <= ans1.se; j++) printf("%d ", ve[j].se); cout << endl; for (int j = ans2.fi; j <= ans2.se; j++) printf("%d ", ve[j].se); cout << endl; return true; } return false; } int main(){ cin >> n >> x1 >> x2; for (int i = 1; i <= n; i++){ int a; scanf("%d", &a); ve.pb(mk(a, i)); } sort(ALL(ve)); for (int i = ve.size()-1; i >= 0; i--){ dp[i] = (ve.size() - i) * ve[i].fi; } if (solve() == false) puts("No"); return 0; }