题意:
给出n个字符串,选择k个字符串,求字典序最小的串。
思路:
dp[i][j]表示从[ i , n ]选择j个字符串得到的字典序最小的串是多少。
转移就是判断第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 */