测评会员优惠活动进行中 · 开通 VIP,有效期内测评不限次 VIP 优惠中 · 测评不限次 立即查看

A25064. 买还是不买

填空题 困难

题目描述

买还是不买

题目描述

小红想用自己喜欢的彩色珠子做一条珠串,于是去一家小店买珠子。店里有很多条彩色的珠串,但店主只卖整串,不拆散零售珠子。于是小红为了得到自己喜欢颜色的珠子,就得买很多条现成的珠串,回家拆了自己拼。

由于店里有上百条珠串,小红只好求助于你,请你写个程序,帮她看看是否有可能买到所有她喜欢颜色的珠子,并且使得多余的珠子尽可能少。

为简单起见,我们用数字 0 到 9、以及英文的 26 个字母的大小写来表示珠子的颜色(即珠子最多有 62 种颜色)。

在样例 1 中,买第 2 条和最后两条珠串是最划算的,因为这样只有 3 颗珠子是多余的。

在样例 2 中,把全部三条珠串都买下也不行,因为还少三颗 R 珠。

输入

输入第一行给出小红想要的珠串。下一行给出正整数 N(≤ 100),随后 N 行,每行给出店里的一条珠串。所有珠串中的珠子不超过 1000 颗。

输出

如果能凑出小红想要的珠串,则在一行中输出 Yes、空格、最少的多余珠子的个数;否则输出 No、空格、凑不出来的珠子的个数。

样例输入1

RYg5
8
gY5Ybf
8R5
12346789
gRg8h
5Y37
pRgYgbR52
8Y
8g

样例输出1

Yes 3

样例输入2

YrRR8RRrY
3
ppRGrrYB225
8ppGrrB25
Zd6KrY

样例输出2

No 3

参考答案

//答案来源于AI #include <iostream> #include <vector> #include <algorithm> #include <string> #include <climits> using namespace std; const int MAX_COLOR = 62; int getIndex(char c) { if (c >= '0' && c <= '9') return c - '0'; else if (c >= 'A' && c <= 'Z') return 10 + (c - 'A'); else if (c >= 'a' && c <= 'z') return 36 + (c - 'a'); return -1; } struct Bead { int len; vector<int> cnt; string s; Bead(string str) : s(str), len(str.size()), cnt(MAX_COLOR, 0) { for (char c : str) { int idx = getIndex(c); if (idx != -1) { cnt[idx]++; } } } }; vector<Bead> beads; vector<int> target(MAX_COLOR, 0); vector<int> total(MAX_COLOR, 0); vector<vector<int>> suffix; int best = INT_MAX; int total_target = 0; int N; void dfs(int idx, vector<int> need, int cur_len) { if (cur_len >= best) { return; } int sum_need = 0; bool all_zero = true; for (int c = 0; c < MAX_COLOR; c++) { if (need[c] > 0) { all_zero = false; sum_need += need[c]; } } if (all_zero) { best = cur_len; return; } if (idx >= N) { return; } for (int c = 0; c < MAX_COLOR; c++) { if (need[c] > suffix[idx][c]) { return; } } if (cur_len + sum_need >= best) { return; } dfs(idx + 1, need, cur_len); bool useful = false; for (int c = 0; c < MAX_COLOR; c++) { if (beads[idx].cnt[c] > 0 && need[c] > 0) { useful = true; break; } } if (useful) { vector<int> new_need = need; for (int c = 0; c < MAX_COLOR; c++) { if (new_need[c] > 0) { new_need[c] = max(0, new_need[c] - beads[idx].cnt[c]); } } dfs(idx + 1, new_need, cur_len + beads[idx].len); } } int main() { string target_str; getline(cin, target_str); total_target = target_str.size(); for (char c : target_str) { int idx = getIndex(c); if (idx != -1) { target[idx]++; } } cin >> N; cin.ignore(); beads.reserve(N); for (int i = 0; i < N; i++) { string s; getline(cin, s); beads.push_back(Bead(s)); } for (int i = 0; i < MAX_COLOR; i++) { total[i] = 0; } for (int i = 0; i < N; i++) { for (int c = 0; c < MAX_COLOR; c++) { total[c] += beads[i].cnt[c]; } } int shortage = 0; bool overall_meet = true; for (int c = 0; c < MAX_COLOR; c++) { if (target[c] > total[c]) { overall_meet = false; shortage += (target[c] - total[c]); } } if (!overall_meet) { cout << "No " << shortage << endl; return 0; } sort(beads.begin(), beads.end(), [](const Bead& a, const Bead& b) { return a.len < b.len; }); suffix.resize(N, vector<int>(MAX_COLOR, 0)); for (int c = 0; c < MAX_COLOR; c++) { suffix[N - 1][c] = beads[N - 1].cnt[c]; } for (int i = N - 2; i >= 0; i--) { for (int c = 0; c < MAX_COLOR; c++) { suffix[i][c] = beads[i].cnt[c] + suffix[i + 1][c]; } } best = INT_MAX; dfs(0, target, 0); cout << "Yes " << best - total_target << endl; return 0; }
上一题 下一题