1004. To Buy or Not to Buy

来源:互联网 发布:j2ee与java的区别 编辑:程序博客网 时间:2024/05/01 07:52

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue

Eva would like to make a string of beads with her favorite colors so she went to a small shop to buy some beads. There were many colorful strings of beads. However the owner of the shop would only sell the strings in whole pieces. Hence in some cases Eva might have to buy several strings to get all the beads she needs. With a hundred strings in the shop, Eva needs your help to tell her whether or not she can get all the beads she needs with the least number of extra beads she has to pay for.

For the sake of simplicity, let's use the characters in the ranges [0-9], [a-z], and [A-Z] to represent the colors. In sample 1, buying the 2nd and the last two strings is the best way since there are only 3 extra beads. In sample 2, buying all the three strings won't help since there are three "R" beads missing.

Input Specification:

Each input file contains one test case. Each case first gives in a line the string that Eva wants. Then a positive integer N (<=100) is given in the next line, followed by N lines of strings that belong to the shop. All the strings contain no more than 1000 beads.

Output Specification:

For each test case, print your answer in one line. If the answer is "Yes", then also output the least number of extra beads Eva has to buy; or if the answer is "No", then also output the number of beads missing from all the strings. There must be exactly 1 space between the answer and the number.

Sample Input 1:
RYg58gY5Ybf8R512346789gRg8h5Y37pRgYgbR528Y8g
Sample Output 1:
Yes 3
Sample Input 2:
YrRR8RRrY3ppRGrrYB2258ppGrrB25Zd6KrY
Sample Output 1:
No 3
由于最近刚接触到DP,再加上题目就叫买与不买,所以就选择了DP来做,至于珠子的记录自然而然地就想到了用62维数组,
写完了才知道不知道该如何做备忘,也硬着头皮交了上去,
结果不堪入目。哈哈
后来也没太多思路,所以就去借鉴一下,别人的,网上搜到可以用DFS+剪枝,这就为我提供了思路,于是就再次动工了呗。
DFS的确是个好方法,但控制不好也就只能面临超时,要想让他和快的搜索到目标,自然不可能让它就这样搜索,
于是乎给他排排序,让可能是正确答案的先被搜到,但基于什么排序呢?
买珠子凑齐目标珠子,尽可能地少,不久讲究利用率吗?
所以可以根据可利用的数量来排序。
排完序就可以进行搜索了,这里搜索的结束条件我加了一个判断(代码注释中)。
# include <iostream>using namespace std;# define ver(a) a >= 97 ? a - 61 : (a >= 65 ? a - 55 : a - 48)      //将各种珠子与各个数字一一对应转化struct Info {
int z[62];                //各种珠子的数量int uesd, total;          //珠子可使用数和总数}bead[100],aim,now;               //商店提供串,目标串,当前串int n;                            //商店串总数int via[100] = { 0 };             //标记是否被使用//该函数用来读取每串珠子
void Ex(Info & a) {               char x;while ((x = getchar()) && x != '\n') {int y = ver(x);a.z[y]++;a.total++;}return;}
//qsort的比较函数,根据珠子未使用数升序排序int cmp(const void * c, const void * d) {Info * a = (Info *)c;Info * b = (Info *)d;if (a->total - a->uesd <= b->total - b->uesd) return -1;return 1;}
//搜索前的准备,void Init(void) {for (int i = 0; i < 62; i++) {for (int j = 0; j < 100; j++) bead[j].z[i] = 0;aim.z[i] = 0;now.z[i] = 0;}for (int i = 0; i < 100; i++) bead[i].total = bead[i].uesd = 0;Ex(aim);cin >> n;getchar();   //这里是为了读取n遗留下来的一个'\n',否则后面会出错for (int i = 0; i < n; i++) Ex(bead[i]);for (int i = 0; i < 100; i++) {for (int j = 0; j < 62; j++) {if (bead[i].z[j] && aim.z[j]) {int re = bead[i].z[j] > aim.z[j] ? aim.z[j] : bead[i].z[j];bead[i].uesd += re;}}}qsort(bead, n, sizeof(Info), cmp);return;}//更新已有的各种珠子的数量Info add(Info a, Info b) {Info c;for (int i = 0; i < 62; i++) c.z[i] = a.z[i] + b.z[i];return c;}
//计算多余珠子数量int num(Info no) {int x = 0;for (int i = 0; i < 62; i++) {int re = aim.z[i] > no.z[i] ? 0 : no.z[i] - aim.z[i];x += re;}return x;}
//检查是否达到需求bool check(Info no) {for (int i = 0; i < 62; i++) {if (no.z[i] < aim.z[i]) return false;}return true;}int Min = 0x7fffffff;void bfs(Info no) {if (Min < num(no)) return; //每次进行选珠子之前,先检查目前选的这些珠子的多余量是否比最少的少,若少则可继续选取珠子,否则返回重选。if (check(no)) {Min = num(no);return;}for (int i = 0; i < n; i++) {if (!via[i]) {via[i] = 1;bfs(add(no, bead[i]));via[i] = -1;}}return;}int main(void) {Init();Min = 0;
//先进行检查全部珠子都买是否满足
for (int i = 0; i < 62; i++) {if (aim.z[i]) {int x = 0;for (int j = 0; j < n; j++) {x += bead[j].z[i];if (x >= aim.z[i]) break;}if (x < aim.z[i]) Min += (aim.z[i] - x);}}if (Min != 0) cout << "No " << Min;else {Min = 0x7fffffff;bfs(now);cout << "Yes " << Min;}return 0;}
原创粉丝点击