题意:
给出 n n n个字符串,选择 k k k个字符串,求字典序最小的串。
思路:
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示从
[
i
,
n
]
[i,n]
[i,n]选择
j
j
j个字符串得到的字典序最小的串是多少。
转移就是判断第
i
i
i个串选或不选。
必须要倒着枚举 参考
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;typedef unsigned long long ull;
typedef pair<ll,ll>PLL;typedef pair<int,int>PII;typedef pair<double,double>PDD;
#define I_int ll
inline ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
#define read read()
#define rep(i, a, b) for(int i=(a);i<=(b);++i)
#define dep(i, a, b) for(int i=(a);i>=(b);--i)
ll ksm(ll a,ll b,ll p){ll res=1;while(b){if(b&1)res=res*a%p;a=a*a%p;b>>=1;}return res;}
const int maxn=4e5+7,maxm=1e6+7,mod=1e9+7;
string s[55];
string dp[55][55];
bool cmp(string a,string b){
return a+b<b+a;
}
int main(){
int n=read,k=read;
rep(i,1,n) cin>>s[i];
sort(s+1,s+1+n,cmp);
for(int i=1;i<=n+1;i++) dp[i][n-i+2]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz";
for(int i=n;i;i--)
for(int j=1;j<=n-i+1;j++)
dp[i][j]=min(dp[i+1][j],s[i]+dp[i+1][j-1]);
cout<<dp[1][k]<<"\n";
return 0;
}
/*
4 3
ode
zaaa
r
atc
*/