链接 G. Good Key, Bad Key
题意
给你1-n个宝箱,每一个 箱子都有一定数量的金币,按顺序开,每一个可以选择用好钥匙或者坏钥匙。
- 好钥匙,一个花费k金币。
- 坏钥匙,不花费金币,但是本个箱子和以后的箱子金币数都减半。
求获得的最大金币数。
思路
贪心,分析题可以知道,坏钥匙越后边用价值越高,而且用完坏钥匙不要用好钥匙得到的贡献最大。
这样我们就可以枚举用好钥匙和坏钥匙的分界即可。
代码
#include <bits/stdc++.h>
#define x first
#define y second
#define rep(x, y, z) for(int x = y; x <= z; x ++)
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
const int N = 1e5 + 10, M = 2 * N;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000000007;
const double eps = 1e-8;
int T;
int n, m;
ll k;
ll a[N];
ll sum[N];
void solve() {
memset(a, 0, sizeof a);
memset(sum, 0, sizeof sum);
cin >> n >> k;
for (int i = 1; i <= n; i ++) cin >> a[i], sum[i] = sum[i - 1] + a[i];
ll ans = 0;
rep (i, 0, n) {
ll res = sum[i] - (ll)i * k;
ll q = 2;
rep (j, i + 1, i + 40) {
if (j > n) break;
res += (a[j] / q);
q *= 2;
}
ans = max(res, ans);
}
cout << ans << endl;
return ;
}
int main() {
ios::sync_with_stdio(false), cin.tie(0);
cin >> T;
while (T --) {
solve();
}
return 0;
}