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] << "
    ";
    }
    
  • 相关阅读:
    修复TabControl在Binding情况下Canvas被复用的问题
    避免缓加载时因违反惯例导致的空引用!
    乱说一气
    WPF中的数据验证
    [zz]GPU architecture
    [zz]DirectX 11 and Shared Model 5.0
    网页栅格系统中的最佳宽度:960px
    复习html标签及其属性
    去除链接虚线边框css
    使用jquery解决IE6不兼容的伪类
  • 原文地址:https://www.cnblogs.com/ZhengkunJia/p/15490670.html
Copyright © 2011-2022 走看看