思路
- 原数组:确定是否使用“礼遇”后的英雄最高得分(可以变换顺序)
- 由于“礼遇”的存在,不能直接对原数组进行排序,需要二进制枚举所有满足条件的情况。
- 由于分数是累加的,也就是前缀和。对于前缀和的话,想要前缀和数组的每一个位置的数都尽量大,则需要将原数组按从大到小的顺序排列。这样就可以保证,在原数组所有可能的排列顺序下,前缀和数组上每一个位置上的数都是最大的。(若不理解,可以随意举例,手动求和)
注意:
题目上说可以自由排列游戏顺序,说的是上面原数组的顺序,而不是题目中的p数组。
CODE
#include<bits/stdc++.h>
#define endl "\n"
#define IOS ios::sync_with_stdio(0), cin.tie(0),cout.tie(0)
#define ft first
#define sd second
#define pii pair<int, int>
#define ll long long int
using namespace std;
const int N = 1e2 + 2;
pii s[N];
int a[N], b[N];
int main()
{
IOS;
int n, k, S;
cin >> n >> k >> S;
for (int i = 0; i < n; i++) cin >> a[i];
for (int i = 0; i < n; i++)
{
int x, y, z, c;
cin >> x >> y >> z >> c;
s[i].ft = max(x, y);
s[i].sd = max(z, c);
}
int ans = 0;
for (int i = 0; i < 1 << n; i++)
{
if (__builtin_popcount(i) > k) continue;
for (int j = 0; j < n; j++)
if (i & 1 << j) b[j] = max(s[j].ft, s[j].sd);
else b[j] = s[j].ft;
sort(b, b + n, greater<int>());
int sum = S, cnt = 0;
for (int j = 0; j < n; j++)
{
sum += b[j];
if (sum >= a[j]) cnt++;
}
if (cnt > ans) ans = cnt;
}
cout << ans << endl;
return 0;
}