小H的硬币游戏
题目大意:
有n个物品排成一排,每个物品都有自己的价值,你每次可以从中挑选两个距离为k的物品取走,问最大的收益。
(如果原来两个物品中间有物品被取走,距离不变)
思路:
贪心。
先按照每个物品的位置mod k以后分类。
如果mod k以后对应的这一组有奇数个物品,那么肯定有一个拿不了,否则肯定都能够拿完。
那么对于个数为奇数的组,我们要从中找出一个价值最小的物品从里面去掉,同时要满足在这个物品左右的物品个数都是偶数(因为相邻两个两两配对)。
1 #include<cstdio> 2 #include<cctype> 3 #include<algorithm> 4 typedef long long int64; 5 inline int getint() { 6 register char ch; 7 while(!isdigit(ch=getchar())); 8 register int x=ch^'0'; 9 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 10 return x; 11 } 12 const int inf=0x7fffffff; 13 const int N=100000; 14 bool cnt[N]; 15 int min[N]; 16 int main() { 17 int n=getint(),k=getint(); 18 int64 sum=0; 19 std::fill(&min[0],&min[k],inf); 20 for(register int i=0;i<n;i++) { 21 cnt[i%k]=!cnt[i%k]; 22 const int x=getint(); 23 sum+=x; 24 if(cnt[i%k]) min[i%k]=std::min(min[i%k],x); 25 } 26 for(register int i=0;i<k;i++) { 27 if(cnt[i%k]) sum-=min[i%k]; 28 } 29 printf("%lld\n",sum); 30 return 0; 31 }