• 「日常训练」Kefa and Company(Codeforces Round #321 Div. 2 B)


    题意与分析(CodeForces 580B)

    (n)个人,告诉你(n)个人的工资,每个人还有一个权值。现在从这n个人中选出m个人,使得他们的权值之和最大,但是对于选中的人而言,其他被选中的人的工资不能超过他的工资+d。
    这题用尺取法可以漂亮的解决。尺取法按照《挑战》一书的定义,是“指对数组保存一对下标(起点和终点),然后根据实际情况交替推进两个端点直到得到答案”的一种方法,因为这种操作“很像是尺蠖(日文中称为尺取虫)爬行的方式”而得名。
    具体到这题就是,都不用二分:按照工资排序后设定前后指针(L,R),然后将(R)向前移动到最大的符合条件的区间,记录并更新长度,然后将(L)更新,再继续这样操作即可。复杂度为(O(n))

    代码

    #include <bits/stdc++.h>
    #define MP make_pair
    #define PB emplace_back
    #define fi first
    #define se second
    #define ZERO(x) memset((x), 0, sizeof(x))
    #define ALL(x) (x).begin(),(x).end()
    #define rep(i, a, b) for (repType i = (a); i <= (b); ++i)
    #define per(i, a, b) for (repType i = (a); i >= (b); --i)
    #define QUICKIO                  
        ios::sync_with_stdio(false); 
        cin.tie(0);                  
        cout.tie(0);
    using namespace std;
    using ll=long long;
    using repType=ll;
    const int MAXN=100000+5;
    int n,d;
    vector<pair<ll,ll> > vec;
    int main()
    {
    	QUICKIO
    	cin>>n>>d;
    	rep(i,1,n)
    	{
    		ll m,s; cin>>m>>s;
    		vec.PB(MP(m,s));
    	}
    	sort(ALL(vec));
    	int L=0,R=-1;
    	ll ans=0, sum=0;
    	while (L<n)
    	{
    		while(R+1<n && vec[R+1].fi-vec[L].fi<d)
    			sum+=vec[++R].se;
    		ans=max(ans,sum);
    		sum-=vec[L++].se;
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    
    如非注明,原创内容遵循GFDLv1.3发布;其中的代码遵循GPLv3发布。
  • 相关阅读:
    [osg][原]自定义osgGA漫游器
    [osg]osg窗口显示和单屏幕显示
    sql中去除重复的数据 select distinct * from table
    Microsoft VBScript 运行时错误 错误 800a005e 无效使用 Null: Replace
    如何解决Access操作或事件已被禁用模式阻止
    sql 中 '' 与 null 的区别
    IsNull、rs、sum
    Access与SQL中的IsNull(),IS NULL的区别
    ASP将Table导出Excel
    ASP如何将table导出EXCEL表格
  • 原文地址:https://www.cnblogs.com/samhx/p/CFR321D2B.html
Copyright © 2020-2023  润新知