zoukankan      html  css  js  c++  java
  • Gym-101810 G ACM International Collegiate Programming Contest, Amman Collegiate Programming Contest (2018)

    题意

    字符串(S)的能量(P(S))定义为

    [P(S)=sum_{i=1}^{n}N_i imes V_i ]

    (N_i)是满足(S_i=S_j)的下标(j(i<jle n))的个数,(V_i)是字符(S_i)(ASCII)码。

    给一个长度为(n)的字符串(s)和一个整数(k),你可以对字符串(s)做最多(k)次操作,每次操作你可以将字符串(s)中的任意一个字符(s_i)变为任意一个小写字母。你的目标是最大化字符串(s)的能量。

    分析

    首先,字符串(s)的字母的顺序不会影响答案,令(cnt[ch])为字符(ch)在字符串(s)中出现的个数,它对答案的贡献为(frac{cnt[ch] imes(cnt[ch]-1)}{2} imes ch)

    从26个字母中选取一部分字母,将字符串(s)中和这些字母相同的所有字母全部变成字母(ch1),选取一个字母(ch2),将字符串(s)中和它相同的字母的一部分变成(ch1)。我们可以枚举(ch1)(ch2),然后用个类似01背包的dp来找选取哪些字母,将字符串中所有相同的字母变成(ch1)

    Code

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<iomanip>
    #include<sstream>
    #include<cstdio>
    #include<string>
    #include<vector>
    #include<bitset>
    #include<queue>
    #include<cmath>
    #include<stack>
    #include<set>
    #include<map>
    #define rep(i,x,n) for(int i=x;i<=n;i++)
    #define per(i,n,x) for(int i=n;i>=x;i--)
    #define sz(a) int(a.size())
    #define rson mid+1,r,p<<1|1
    #define pii pair<int,int>
    #define lson l,mid,p<<1
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define se second
    #define fi first
    using namespace std;
    const double eps=1e-8;
    const int mod=1e9+7;
    const int N=1e5+10;
    const int inf=1e9;
    int T,n,k;
    int cnt[30];
    ll dp[30][5010];
    ll ans=0;
    int foo,bar;
    ll cal(ll x,int y){
    	return x*(x-1)/2*(y+'a');
    }
    ll solve(int c,int r){
    	if(c==foo||c==bar) return solve(c+1,r);
    	if(c==26){
    		int mn=min(cnt[bar],r);
    		r-=mn;
    		return cal(cnt[bar]-mn,bar)+cal(cnt[foo]+k-r,foo);
    	}
    	if(~dp[c][r]) return dp[c][r];
    	dp[c][r]=solve(c+1,r)+cal(cnt[c],c);
    	if(r>=cnt[c]){
    		dp[c][r]=max(dp[c][r],solve(c+1,r-cnt[c]));
    	}
    	return dp[c][r];
    }
    int main(){
    	//ios::sync_with_stdio(false);
    	//freopen("in","r",stdin);
    	scanf("%d",&T);
    	while(T--){
    		scanf("%d%d",&n,&k);
    		memset(cnt,0,sizeof(cnt));
    		ans=0;
    		rep(i,1,n){
    			char c;
    			cin>>c;
    			cnt[c-'a']++;
    		}
    		for(int i=0;i<26;i++) ans+=cal(cnt[i],i);
    		for(int i=0;i<26;i++){
    			for(int j=0;j<26;j++) if(i!=j){
    				memset(dp,-1,sizeof(dp));
    				foo=i;bar=j;
    				ans=max(ans,solve(0,k));
    			}
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Android Studio相关
    iOS自动签名网站
    Ruby开发小记
    Python全栈之路目录结构
    不会docker的开发
    Centos7安装python3
    03 centos7的基本价绍
    02 centos虚拟机安装
    01 Linux虚拟机的安装
    跨域问题的解决
  • 原文地址:https://www.cnblogs.com/xyq0220/p/13284060.html
Copyright © 2011-2022 走看看