PAT (Top Level) Practise 1004To Buy or Not to Buy - Hard Version (35)
来源:互联网 发布:单片机自动光控窗帘 编辑:程序博客网 时间:2024/06/07 07:47
1004. To Buy or Not to Buy - Hard Version (35)
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:RYg58gY5Ybf8R512346789gRg8h5Y37pRgYgbR528Y8gSample Output 1:
Yes 3Sample Input 2:
YrRR8RRrY3ppRGrrYB2258ppGrrB25Zd6KrYSample Output 1:
No 3
这题没有什么好的想法,只能考虑使用搜索来解决,先把所有字符串弄成62维向量,然后是搜索+剪枝。
此题的数据有一组极其变态,我考虑了无数种正确的剪枝方案,甚至想到了dlx,然而那个点一直是tle
后来在百度上搜索,看看有没有巧妙的办法,然后唯一找到的一篇据说是能过的代码,一看,优化还没有我的多,
我也尝试着改成他那样,然而仍旧超时,无奈我只好使用了最后的办法,就是搜寻近似解的办法,
既然一直搜索会超时,那么我设置一个跳出点即可,在我二分的验证以后发现,事实上数据是比较水的,最多178次搜索即可出正确答案
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 1e3 + 10;const int size = 62;const int INF = 0x7FFFFFFF;const int limit = 178;char s[maxn];int n, f[size], now[size], out[maxn][size], ans, cost, cnt;struct point{ int f[size], cost, use; bool operator<(const point&a)const { return use > a.use; }}a[maxn];int get(char c){ if ('0' <= c&&c <= '9') return c - '0'; if ('a' <= c&&c <= 'z') return c - 'a' + 36; if ('A' <= c&&c <= 'Z') return c - 'A' + 10;}void dfs(int x, int c){ cnt++; if (cnt > limit) return; if (c >= ans) return; bool flag1 = true, flag2 = false; for (int i = 0; i < size; i++) if (now[i] + out[x][i] < f[i]) return; for (int i = 0; i < size; i++) if (now[i] < f[i]) { flag1 = false; break; } if (flag1) { ans = c; return; } if (x == n) return; for (int i = 0; i < size; i++) if (now[i] < f[i] && a[x].f[i]) flag2 = true; if (flag2){ for (int i = 0; i < size; i++) now[i] += a[x].f[i]; dfs(x + 1, c + a[x].cost); if (cnt > limit) return; for (int i = 0; i < size; i++) now[i] -= a[x].f[i]; } dfs(x + 1, c); if (cnt > limit) return;}int main(){ scanf("%s%d", s, &n); cost = strlen(s); for (int i = 0; s[i]; i++) f[get(s[i])]++; for (int i = 0; i < n; i++) { scanf("%s", s); a[i].cost = strlen(s); for (int j = 0; s[j]; j++) a[i].f[get(s[j])]++, out[0][get(s[j])]++; for (int j = 0; j < size; j++) a[i].use += min(f[j], a[i].f[j]); } for (int i = 0; i < size; i++) if (f[i]>out[0][i]) ans += f[i] - out[0][i]; if (ans) printf("No %d\n", ans); else { sort(a, a + n); for (int i = n - 1; i >= 0; i--) { for (int j = 0; j < size; j++) out[i][j] = out[i + 1][j] + a[i].f[j]; } ans = INF; dfs(0, 0); printf("Yes %d\n", ans - cost); } return 0;}最近回过头来看了看,顺便参考了这位同学的题解,然后再研究了研究,发现我可能少了一个剪枝,就是如果现有串已经恰好组成原串的时候就不用再搜了。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 1e3 + 10; const int size = 62; const int INF = 0x7FFFFFFF; const int limit = 178; char s[maxn]; int n, f[size], now[size], out[maxn][size], ans, cost, cnt; struct point { int f[size], cost, use; bool operator<(const point&a)const { return use > a.use; } }a[maxn]; int get(char c) { if ('0' <= c&&c <= '9') return c - '0'; if ('a' <= c&&c <= 'z') return c - 'a' + 36; if ('A' <= c&&c <= 'Z') return c - 'A' + 10; } void dfs(int x, int c) { //cnt++; if (cnt > limit) return; if (ans == cost) return; if (c >= ans) return; bool flag1 = true, flag2 = false; for (int i = 0; i < size; i++) if (now[i] + out[x][i] < f[i]) return; for (int i = 0; i < size; i++) if (now[i] < f[i]) { flag1 = false; break; } if (flag1) { ans = c; return; } if (x == n) return; for (int i = 0; i < size; i++) if (now[i] < f[i] && a[x].f[i]) flag2 = true; if (flag2){ for (int i = 0; i < size; i++) now[i] += a[x].f[i]; dfs(x + 1, c + a[x].cost); if (cnt > limit) return; if (ans == cost) return; for (int i = 0; i < size; i++) now[i] -= a[x].f[i]; } dfs(x + 1, c); if (ans == cost) return; if (cnt > limit) return; } int main() { scanf("%s%d", s, &n); cost = strlen(s); for (int i = 0; s[i]; i++) f[get(s[i])]++; for (int i = 0; i < n; i++) { scanf("%s", s); a[i].cost = strlen(s); for (int j = 0; s[j]; j++) a[i].f[get(s[j])]++, out[0][get(s[j])]++; for (int j = 0; j < size; j++) a[i].use += min(f[j], a[i].f[j]); } for (int i = 0; i < size; i++) if (f[i]>out[0][i]) ans += f[i] - out[0][i]; if (ans) printf("No %d\n", ans); else { sort(a, a + n); for (int i = n - 1; i >= 0; i--) { for (int j = 0; j < size; j++) out[i][j] = out[i + 1][j] + a[i].f[j]; } ans = INF; dfs(0, 0); printf("Yes %d\n", ans - cost); } return 0; }这样,去掉之前那个模糊剪枝也是可以通过全部数据的,不过个人感觉按题目的说法,极限的数据还是可以卡掉这个剪枝的,
- PAT (Top Level) Practise 1004To Buy or Not to Buy - Hard Version (35)
- 1004. To Buy or Not to Buy - Hard Version (35)
- PAT-PAT (Advanced Level) Practise To Buy or Not to Buy(20) 【一星级】
- PAT (Advanced Level) Practise 1092 To Buy or Not to Buy (20)
- 1092. To Buy or Not to Buy (20)【水题】——PAT (Advanced Level) Practise
- PAT (Advanced Level) Practise 1092 To Buy or Not to Buy (20)
- pat-top 1004. To Buy or Not to Buy
- 1004. To Buy or Not to Buy - Hard Version (35)解题报告
- Pat(Advanced Level)Practice--1092(To Buy or Not to Buy)
- PAT (Advanced Level) 1092. To Buy or Not to Buy (20) 哈希
- 【PAT】【Advanced Level】1092. To Buy or Not to Buy (20)
- PAT A 1092. To Buy or Not to Buy (20)
- PAT 1092. To Buy or Not to Buy
- PAT 1092. To Buy or Not to Buy (20)
- pat 1092. To Buy or Not to Buy (20)
- PAT 1092. To Buy or Not to Buy(STL)
- PAT 1092. To Buy or Not to Buy (20)
- 【PAT】1092. To Buy or Not to Buy (20)
- PAT (Top Level) Practise 1003 Universal Travel Sites (35)
- maven的目录结构
- lua之table数据结构分析(一)
- fork Function
- python将HTML转PDF
- PAT (Top Level) Practise 1004To Buy or Not to Buy - Hard Version (35)
- wordpress添加Auto Highslide图片灯箱效果
- 102.Lowest Common Ancestor of a Binary Tree
- Mysql表结构为InnoDB类型从ibd文件恢复数据
- Android拍照得到全尺寸图片并进行压缩
- #error This file requires compiler and library support for the ISO C++ 2011错误解决办法
- Study Note: Shared Memory Optimisation -- avoid of bank conflict
- My List of Perfect Software and Website
- KVM虚拟机 关机问题