Codeforces Round 1044 (Div. 2) 总结
A
属于弱智题,不难发现有 \(a_1 / a_2 * a_2 / a_3 \dots\) 以此类推,所以发现只需要判断数组里有没有两个相同的元素即可。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
const int N = 1e3+100;
int n, a[N];
bool check[N];
void solve () {
cin >> n;
bool flag = false;
memset(check, false, sizeof(check));
for (int i = 1;i <= n;i++) {
cin >> a[i];
if (check[a[i]]) flag = true;
check[a[i]] = true;
}
if (flag) cout << "YES\n";
else cout << "NO\n";
}
int main () {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int _ = 1; cin >> _;
while (_--) solve();
return 0;
}
B
这道题需要动点脑子,贪心的确巧妙,手玩样例发现贪心规律:尽量让大的和大的一起捆绑处理。
所以得出做法:排序然后两个两个处理,如果是奇数就把最小的单独加上,否则直接就是 \(ans\)。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
const int N = 2e5+100;
ll n, g[N];
void solve () {
cin >> n;
for (int i = 1;i <= n;i++) cin >> g[i];
sort(g+1, g+n+1);
if (!(n&1)) {
ll ans = 0;
for (int i = 2;i <= n;i+=2) ans += g[i];
cout << ans << "\n";
} else {
ll ans = 0;
for (int i = 3;i <= n;i+=2) ans += g[i];
ans += g[1];
cout << ans << "\n";
}
}
int main () {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int _ = 1; cin >> _;
while (_--) solve();
return 0;
}
D
一道很有趣的线性 dp,通过手玩样例可以发现,对于每一个怪兽只有两种方式解决:
- 让其摔得最惨然后补刀。
- 直接留到最后杀死。
那么得到这两个之后,我们考虑 dp 的状态为:\(dp_i\) 表示考虑到第 \(i\) 位的最优答案。
那么根据上面我们得到的性质不难推出转移方程:
\[dp_i = \max(dp_{i-1} + (h_i - 1), \,\, dp_{i-2} + h_{i-1} + \max(0, h_i - (i-1)))
\]
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
const int N = 2e5+100;
ll n, h[N], dp[N];
void solve () {
cin >> n;
for (int i = 1;i <= n;i++) cin >> h[i];
memset(dp, 0, sizeof(dp));
dp[0] = 0, dp[1] = h[1];
for (int i = 2;i <= n;i++)
dp[i] = min(dp[i-1] + h[i]-1, dp[i-2] + h[i-1] + max(0ll, h[i]-(i-1)));
cout << dp[n] << "\n";
}
int main () {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int _ = 1; cin >> _;
while (_--) solve();
return 0;
}
浙公网安备 33010602011771号