2018山东冬令营:硬币游戏IV( 好题!)
硬币游戏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
岂曰无衣?与子同袍。王于兴师,修我戈矛。与子同仇!
岂曰无衣?与子同泽。王于兴师,修我矛戟。与子偕作!
岂曰无衣?与子同裳。王于兴师,修我甲兵。与子偕行!