zoukankan      html  css  js  c++  java
  • 【题解】ABC225F

    题意

    给定 (n) 个仅由小写英文字母组成的字符串,从中选出 (k) 个,以任意顺序排列,使得得到的字符串字典序最小。
    输出字典序最小的字符串。

    做法

    先将所有字符串按照如下方式排序:

    bool cmp(string A, string B){
      return A+B<B+A;
    }
    

    然后DP。
    (dp[i][j]) 表示从后 (i) 个字符串中选择 (j) 个能得到的字典序最小的字符串,转移如下:
    (dp[i][j]=min(dp[i+1][j],str[i]+dp[i+1][j-1]))
    答案即为 (dp[1][k])
    妙就秒在把贪心决策提前处理了。
    而且这个DP为什么是从后往前而不是从前往后,因为我们的目的是保证字典序最小,字典序更注重前面部分的串而不是后面,把后面都处理好了那么前面的大小可以决定一切。

    代码

    string st[maxn];
    string dp[maxn][maxn];
    bool cmp(string A, string B){
    	return A+B < B+A;
    }
    int main(){
    	n=rd(); k=rd();
    	for(int i(1);i<=n;++i){
    		cin >> st[i];
    		len += st[i].size();
    		ln[i] = st[i].size();
    		for(int j(0);j<ln[i];++j){
    			hs[i]*=26; hs[i]+=st[i][j];
    		}
    	}
    	sort(st+1,st+1+n,cmp);
    	for(int i(1);i<=n+1;++i)
    		dp[i][n-i+2]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz";
    	for(int i(n);i>=1;--i){
    		for(int j(1);j<=n-i+1;++j){
    			dp[i][j]=min(dp[i+1][j],st[i]+dp[i+1][j-1]);
    //			printf("dp[%d][%d]=",i,j);cout<<dp[i][j]<<"
    ";
    		}
    	}
    	cout << dp[1][k] << "
    ";
    }
    
  • 相关阅读:
    一步一步学数据结构之(动态申请二维数组)
    运维自动化
    oracle查看登录到oracle服务器的客户端ip
    权限
    windows下使用SQLPLUS制作BAT执行SQL文件
    rsyslog传输type
    C经典实例
    mysql导出数据库数据及表结构
    解决oracle11g无法导出空表问题
    opennebula onenebula
  • 原文地址:https://www.cnblogs.com/ZhengkunJia/p/15490670.html
Copyright © 2011-2022 走看看