.article-info-tag,button{text-transform:uppercase}.day,.postMeta,.postSticky{position:relative}.postTitle a:link,html{-webkit-tap-highlight-color:transparent}#blog-calendar,.code-copay-btn,.code-hljs-len,.hidden{visibility:hidden}#EntryTag,#blogTitle h1{margin-top:20px}#EntryTag a,.postSticky{background:#6fa3ef}#blogTitle h1 a:hover,.dayTitle a,a,a:active,a:link,a:visited{color:#5c8ec6}#calendar table a:hover,#navList a:hover,.postDesc a:hover,a:active,a:hover,a:link,a:visited,button{text-decora…ryTag a:visited{color:#666}#BlogPostCategory a,#EntryTag a{height:20px;line-height:20px;color:#fff!important;padding:3px 5px;border-radius:3px;margin:2px 5px 0;text-decoration:none;font-size:14px}#BlogPostCategory a:hover,#EntryTag a:hover{transition:all .3s linear 0s;opacity:.8}#topics .postDesc{padding-left:0;width:100%;text-align:left;color:#666;margin-top:5px;background:0 0}.feedbackListSubtitle-louzhu:after,.feedbackListSubtitle:after,.feedbackListSubtitle:before{top:11px;right:100%;left:-1

P7412 [USACO21FEB] Year of the Cow S 题解

谷首A

话说十二生肖一开始不是鼠吗?

Description

Solution

贪心

我们考虑将时间轴分成 \(\frac n {12}\) 块,然后计算有必须经过的年份之间的距离,贪心的选取最远的 \(k-1\) 个距离跳过。

为什么是 \(k-1\) 呢?因为我们要首先跳到最远的点上去。

细节见代码

Code

/*If you are full of hope,you will be invincible*/
#include <ctime>
#include <cstdio>
#include <random>
#include <cstring>
#include <iostream>
#include <algorithm>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
#include<ext/pb_ds/priority_queue.hpp>
#define ri register int
typedef long long ll;
std::mt19937 hpy(time(nullptr)+(unsigned long long)(new char));
using std::cin;
using std::cout;
constexpr int inf=0x3f3f3f3f,N=1e5+1;
int a[N],tim[N],n,cnt,k;
bool cmp(int tx,int ty){return tx>ty;}
std::priority_queue<int> Q;//用优先队列来存储最远的k个距离
int main(int argc,const char *argv[]){
	cin >> n >> k;
	k--;
	for(ri i=1;i<=n;++i) cin >> a[i];
	std::sort(a+1,a+1+n);//对年份排序,方便计算差值
	for(ri i=1;i<=n;++i) {
	    if(!cnt) tim[++cnt] = a[i]/12+1;//计算哪些时间段有必须去的年份
	    else if(tim[cnt]!=a[i]/12+1) tim[++cnt]=a[i]/12+1;
	}
	for(ri i=1;i<=cnt;++i) {
	    if(tim[i]-tim[i-1]!=1) Q.push(tim[i]-tim[i-1]-1);//计算时间差
	}
	for(ri i=1;i<=k&&!Q.empty();++i) Q.pop();//选取k个点跳过
    int res = cnt*12;//有cnt个时间段必须经过
    while(!Q.empty()) {
        res += Q.top()*12;//这些时间差必须经过,所以要加12
        Q.pop();
    }
    cout << res;
}
posted @ 2021-04-08 20:47  feicheng  阅读(161)  评论(0编辑  收藏  举报