硬币游戏IV
时间限制: 1 Sec 内存限制: 128 MB提交: 193 解决: 47
[ 提交][ 状态][ 讨论版]
题目描述
小H参加了一场神秘的游戏。游戏中有n堆硬币,第i堆价值ai。每次小H可以选择编号相差k的硬币同时拿走。注意拿走后硬币不进行重标号。小H想知道最多能拿走多大价值的硬币。
输入
第一行两个整数n,k。
第二行n个整数。第i个整数表示ai。
第二行n个整数。第i个整数表示ai。
输出
一行一个整数,表示拿走硬币的最大价值。
样例输入
7 3
7 5 8 6 4 3 2
样例输出
33
提示
对于20%的数据,n<=20。
对于40%的数据,n<=2000。
对于另外20%的数据,k<=10。
对于100%的数据,n<=100000,k<=n,ai<=1000000000。
【】
题目给的 数据很XX蛋, 没有说明白下限, 我以为会有负数的情况, 如果考虑到负数, 那么这道题就更
不容易了。
【解题时遇到的问题】
选择编号相差K 的 的两个, 任意的 编号相差情况, 如果单一考虑 可能就直接从1- k 然后所以的情况加起来
但是 仔细想这是不对的, 比如 k=3 ; a[1] + a[4] a[4] + a[7} 这里就会有歧义,是 4和1 呢 还是4 和7
【思路】
利用一个Vector 二维数组; 行是从1-k 列存的是,对于1-k中从 i 开始,i+k 的数 依次往后 相加;
会发现 当 每一行中 个数是 偶数时 是所有之和; 当为奇数时,必然要去掉一个数, 一个最小而又符合题意的数。
记录下标, 当为奇数时可以去掉,当是偶数时,无法去掉,
具体可以看代码;
在vector 里 存了个pair 结构体, 一个放数据,一个放 对应的下标
【代码】
//#include <bits/stdc++.h>
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <math.h>
#include <cstring>
#include <string>
#include <queue>
#include <deque>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <utility>
#include <set>
#include <bitset>
#include <vector>
#define mem(a,b) memset(a,b,sizeof(a))
#define findx(x,b,n) lower_bound(b+1,b+1+n,x)-b
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w",stdout)
#define SHUT ios_base::sync_with_stdio(false); cout.setf(ios::fixed); cout.precision(20); cout.tie(nullptr); cin.tie(nullptr);
#define lson rt << 1, l, mid
#define rson rt << 1|1, mid + 1, r
#define FI(n) IO::read(n)
#define Be IO::begin()
using namespace std;
typedef long long ll;
const double PI=acos(-1);
const int INF=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e6+5;
const int MAXN=50005;
const int MOD=1e9+7;
const int mod=1e9+7;
int dir[5][2]={0,1,0,-1,1,0,-1,0};
ll sum;
pair<ll,ll>P;
ll a[maxn];
map<ll,ll>mp;
vector<pair<ll,ll> >V[maxn];
int cmp(pair<ll,ll> a,pair<ll,ll> b)
{
return a.first<b.first;
}
int main()
{
ll n,k;
cin>>n>>k;
sum=0;
mem(a,0);
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=k;i++)
{
ll cot=0;
for(int j=i;j<=n;j+=k)
{
V[i].push_back(make_pair(a[j],++cot));
}
}
for(int i=1;i<=k;i++)
{
if( (V[i].size())%2==0 )
{
for(int j=0;j<V[i].size();j++)
sum+=V[i][j].first;
}
else
{
sort(V[i].begin(),V[i].end(),cmp);
for(int j=0;j<V[i].size();j++)
{
if( (V[i][j].second)%2==1 )
{
for(int k=0;k<V[i].size();k++)
sum+=V[i][k].first;
sum-=V[i][j].first;
break;
}
}
}
}
cout<<sum<<endl;
return 0;
}
123