zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 108 (Rated for Div. 2)(C~D)

    传送门

    C. Berland Regional

    题意:一共2e5个学生,告诉你他们的学校和能力。设k表示一个队伍的人数,一个学校可以派出任意个队伍。问当k从1至n时,所有学校能派出最大能力之和。

    题解:考虑暴力解法,先将学生放入学校的vector排序,枚举k与学校,易知学校人数不能整除k时,将会有余数个人不能加入和,这里用前缀和优化一下即可。但目前还是个n方的解法,这里我们剪枝一下。当某个学校人数小于k,这个学校就我不想再枚举。这里我们对学校按人数排序,用一个单指针记入第一个学校,当第一个学校人数小于k时,就使指针往后移。

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    using namespace std;
    #define ll long long
    const ll N=2e5+7;
    ll t,n,a[N],b[N],sum[N];
    vector<ll>ho[N];
    pair<ll,ll>pos[N];
    bool cmp(ll a,ll b){
    	return a>b;
    }
    int main(){
    	scanf("%lld",&t);
    	while(t--){
    		scanf("%lld",&n);
    		for(int i=1;i<=n;i++){
    			ho[i].clear();
    			sum[i]=0;
    		}
    		for(int i=1;i<=n;i++){
    			scanf("%lld",&a[i]);
    		}
    		for(int i=1;i<=n;i++){
    			scanf("%lld",&b[i]);
    		}
    		for(int i=1;i<=n;i++){
    			ho[a[i]].push_back(b[i]);
    		}
    		for(int i=1;i<=n;i++){
    			sort(ho[i].begin(),ho[i].end(),cmp);
    		}
    		for(int i=1;i<=n;i++){
    			ll len=ho[i].size();
    			pos[i].first=len;
    			pos[i].second=i;
    			for(int j=1;j<len;j++){
    				ho[i][j]+=ho[i][j-1];
    			}
    		}
    		sort(pos+1,pos+1+n);
    		int p=1;
    		for(int i=1;i<=n;i++){
    			while(p<=n&&pos[p].first<i){
    				p++;
    			}
    			for(int j=p;j<=n;j++){
    				ll len=pos[j].first;
    				ll now=pos[j].second;
    				ll to=len-len%i;
    				sum[i]+=ho[now][to-1];
    			}
    		}
    		for(int i=1;i<=n;i++){
    			printf("%lld ",sum[i]);
    		}puts("");
    	}
    }
    

    D. Maximum Sum of Products

    题意:给一个数组a,与数组b,你可以倒置a中一段,求最大的ai*bi之和。

    题解:这种题目,很明显不能贪心,所以要暴力求解。枚举a中的每一段,然后每一段由于会倒置,所以贡献要重新算,这样的复杂度是O(n * n * n),我们发现每一段的贡献可以dp算出来,所以时间降至n方。

    #include<iostream>
    #include<cstring>
    using namespace std;
    #define ll long long
    const ll N=5007;
    ll n,a[N],b[N],px[N];
    ll f[N][N];
    ll dfs(ll l,ll r){
    	if(l==r){
    		return a[l]*b[l];
    	}
    	else if(l+1==r){
    		return a[l]*b[r]+a[r]*b[l];
    	}
    	if(f[l][r]!=-1){
    		return f[l][r];
    	}
    	return f[l][r]=a[l]*b[r]+a[r]*b[l]+dfs(l+1,r-1);
    }
    int main(){
    	memset(f,-1,sizeof(f));
    	scanf("%lld",&n);
    	for(int i=1;i<=n;i++){
    		scanf("%lld",&a[i]);
    	}
    	for(int i=1;i<=n;i++){
    		scanf("%lld",&b[i]);
    		px[i]=px[i-1]+a[i]*b[i];
    	}
    	ll ans=0;
    	for(int i=1;i<=n;i++){
    		for(int j=i;j<=n;j++){
    			ans=max(ans,px[i-1]+px[n]-px[j]+dfs(i,j));
    		}
    	}
    	printf("%lld
    ",ans);
    }
    
  • 相关阅读:
    前端博客收集
    Oracle 数据库性能调优
    vue解决跨域问题
    IIS相关问题及解决方案
    《软件测试工程师》学习笔记
    Matlab学习笔记(一)
    排序算法及分析
    Silverlight学习笔记——跨域调用
    Matlab学习笔记(三)
    C#的一些必备技术
  • 原文地址:https://www.cnblogs.com/whitelily/p/14721075.html
Copyright © 2011-2022 走看看