2018山东冬令营:硬币游戏IV( 好题!)

 硬币游戏IV

时间限制: 1 Sec  内存限制: 128 MB
提交: 193  解决: 47
[提交][状态][讨论版]

题目描述

小H参加了一场神秘的游戏。游戏中有n堆硬币,第i堆价值ai。每次小H可以选择编号相差k的硬币同时拿走。注意拿走后硬币不进行重标号。小H想知道最多能拿走多大价值的硬币。

输入

第一行两个整数n,k。
第二行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


posted @ 2018-03-11 20:04  Sizaif  阅读(229)  评论(0编辑  收藏  举报