A. The Man who became a God
题意:给n个长度的一串数字:a1, a2 ......., an.在可以把这串数字分成k个组的情况下使得每个组的f(l, r)相加总和最小。
f(l, r) = |al - al + 1| + |al + 1 - al + 2| +......+ | ar - 1 - ar|.

思路:将所有相邻两个数之间的的差值储存起来,从大到小进行排序并且相加(nums),最后用总和(nums)减去前k-1个值得出来的结果就是所需要的答案。
代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
void solve()
{
int n, k;
cin >> n >> k;
int a[510];
for (int i = 0; i < n; i++) cin >> a[i];
ll nums = 0;
vector<int> v;
for (int i = 0; i < n - 1; i++) {
v.push_back(abs(a[i] - a[i + 1]));
nums += v.back();
}
sort(v.rbegin(), v.rend());
for (int i = 0; i < k - 1; i++) {
nums -= v[i];
}
cout << nums << endl;
}
int main()
{
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
B. Hamon Odyssey
题意:给一个长度为n的数组a1, a2 ......., an.可以任意切割分组,在满足每个组的f(l, r)的值都是最小值(0)的情况下求最大可以分成多少各组。
f(l, r)=al & al + 1&al + 2&…&ar.
思路: 既然题目要求的是满足最小值的情况下可以最大分成多少个组,那就可以把f(l, r)是否等于0作为判断条件进行分组。
代码:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 2e5 + 10;
void solve()
{
int n;
cin >> n;
int a[N];
for (int i = 0; i < n; i++) cin >> a[i];
int cur = a[0];//用cur来继承
int p = 1;
for (int i = 0; i < n; i++) {
cur &= a[i];
if (cur == 0) {
if (i == n - 1) break;
p++;
cur = a[i + 1];
}
}
//最后一个组并不构成最小值0,所以总数--;
if (cur != 0) p--;
p = max(p, 1);
cout << p << endl;
}
int main()
{
int t;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
884

被折叠的 条评论
为什么被折叠?



