这题用 DFS 暴力搜索,对商店里的串挨个判断买或不买,状态是“当前已经买下的珠子,当前正犹豫买不买的串”。
做两个剪枝即可,一个最优性剪枝,一个可行性剪枝:当前需要额外购买的珠子个数已经超过了最优解时剪掉,当前选择已经不可能买全所有珠子时剪掉。
搜索前先做出一个预处理数组,储存第 i~n-1 个串包含的珠子情况。DFS 到达每个状态时,首先处理一遍已经买的珠子,得到已经额外买下的珠子数量,顺便判断一下是不是已经买齐,然后做那两个剪枝,再往下递归。
珠子数量我直接用 int[256] 存了,丢掉个常数优化应该没啥问题,还省点力气。这个搜索跑起来挺快的,十几ms就能AC。:P
#include <iostream>
using namespace std;
const int maxn = 105;
const int maxl = 1005;
const int INF = 0x3f3f3f3f;
int shop[maxn][256], need[256], have[256], rem[maxn][256];
int n, tot, extra = INF;
char s[maxl];
void dfs(int cur) {
int ex = 0, lk = tot;
for (int i = 0; i < 256; i++) {
int t = min(need[i], have[i]);
ex += have[i] - t;
lk -= t;
}
if (cur == n) {
if (!lk) extra = min(extra, ex);
return;
}
if (ex >= extra) return;
for (int i = 0; i < 256; i++) {
if (have[i] + rem[cur][i] < need[i]) return;
}
for (int i = 0; i < 256; i++)
have[i] += shop[cur