• 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);
    }
    
  • 相关阅读:
    string.Format组合跳转路径
    jquery 设置asp:dropdownlist 选中项
    asp:UpdatePanel中js失效问题已解决
    repeater 一个td多个div显示图片
    aps.net js获取服务器控件
    nfs—文件转换器
    Linux之文件权限
    关于Linux与Windows的在服务器的一些区别
    关于Linux目录结构的理解
    新的旅程
  • 原文地址:https://www.cnblogs.com/whitelily/p/14721075.html
Copyright © 2020-2023  润新知