先判断Yes/No,然后暴力深搜,要注意遍历时先遍历选中此字符串的情况,再不选中,否则最后两个会超时
#pragma warning(disable:4996)
#include<string>
#include<iostream>
#include<cstring>
using namespace std;
int ID(char x) {
if (x >= '0' && x <= '9') return x - '0';
if (x >= 'a' && x <= 'z') return x - 'a' + 10;
if (x >= 'A' && x <= 'Z') return x - 'A' + 36;
return -1;
}
const int maxn = 62, inf = 0x3f3f3f3f;
int num[62];
string all[105], s;
int N, ans, _ans;
void dfs(int i) {
if (_ans >= ans) return;
bool _ok = true;
for (int k = 0; k < maxn; ++k)
if (num[k]) { _ok = false; break; }
if (_ok) { ans = _ans; return; }
if (i >= N) return;
string str;
for (auto x : all[i]) {
if (num[ID(x)]) --num[ID(x)], str += x;
else ++_ans;
}
dfs(i + 1);
_ans -= all[i].size() - str.size();
for (auto x : str)
++num[ID(x)];
dfs(i + 1);
}
int main() {
#ifdef _DEBUG
freopen("in", "r", stdin);
#endif // _DEBUG
cin >> s >> N;
for (auto x : s) ++num[ID(x)];
for (int i = 0; i < N; ++i) cin >> all[i];
for (int i = 0; i < N; ++i)
for (auto x : all[i])
--num[ID(x)];
for (int i = 0; i < maxn; ++i)
ans += num[i] > 0 ? num[i] : 0;
if (ans) { printf("No %d\n", ans); return 0; }
memset(num, 0, sizeof(num));
for (auto x : s) ++num[ID(x)];
ans = inf, dfs(0);
printf("Yes %d\n", ans);
}