tag:【枚举】
根据题意:可同时抓取 i 和 i+k 的两颗宝石
可得头部为i的数列
————————————
而一共可以得到
k条头部分别为1,2,3,……,k的数列
——————————————
——————————————
——————————————
如果数列的长度为偶数,则可以全部抓取
如果数列的长度为奇数,则至少放弃一个。
枚举,找到放弃的那一个即可。
#include <iostream>
#include <vector>
using namespace std;
const int N = 1e6 + 10;
typedef long long LL;
int n, k;
LL w[N], s[N];
vector<int> sub(vector<int> &A, int b)
{
vector<int> B;
while(b)
{
B.push_back(b%10);
b/=10;
}
vector<int> C;
for (int i = 0, t = 0; i < A.size(); i ++ )
{
t = A[i] - t;
if (i < B.size()) t -= B[i];
C.push_back((t + 10) % 10);
if (t < 0) t = 1;
else t = 0;
}
while (C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
vector<int> add(vector<int> &A, int b)
{
vector<int> B;
while(b)
{
B.push_back(b%10);
b/=10;
}
vector<int> C;
int t = 0;
for (int i = 0; i < max(A.size(),B.size()); i ++ )
{
if(i < A.size()) t += A[i];
if (i < B.size()) t += B[i];
C.push_back(t % 10);
t /= 10;
}
if (t) C.push_back(t);
return C;
}
int main()
{
cin >> n >> k;
for( int i = 1; i <= n; i++ ) cin >> w[i];
vector <int> res;
res.push_back(0);
for( int i = 1;i <= k; i ++ )
{
int cnt = 0;
int minn;
int pos;
int j = i;
for(; j <= n; j += k ) cnt++;
if(w[i] < w[j - k]) minn = w[i], pos = i;
else minn = w[j - k], pos = j - k;
for(int jj = i; jj <= n; jj += 2 * k)
{
if(minn > w[jj]) minn = w[jj], pos = jj;
}
// cout << cnt << endl;
if(cnt == 1) continue;
for(int jj = i; jj <= n; jj += k)
{
res = add(res, w[jj]);
}
//枚举
if(cnt % 2 == 1) res = sub(res, w[pos]);
}
for (int i = res.size() - 1; i >= 0; i -- ) cout << res[i];
cout << endl;
return 0;
}