在一个火车旅行很受欢迎的国度,你提前一年计划了一些火车旅行。在接下来的一年里,你要旅行的日子将以一个名为 days 的数组给出。每一项是一个从 1 到 365 的整数。火车票有三种不同的销售方式:
通行证允许数天无限制的旅行。 例如,如果我们在第 2 天获得一张为期 7 天的通行证,那么我们可以连着旅行 7 天:第 2 天、第 3 天、第 4 天、第 5 天、第 6 天、第 7 天和第 8 天。
返回你想要完成在给定的列表 days 中列出的每一天的旅行所需要的最低消费。
输入:days = [1,4,6,7,8,20], costs = [2,7,15]
输出:11
解释:
例如,这里有一种购买通行证的方法,可以让你完成你的旅行计划:
在第 1 天,你花了 costs[0] = $2 买了一张为期 1 天的通行证,它将在第 1 天生效。
在第 3 天,你花了 costs[1] = $7 买了一张为期 7 天的通行证,它将在第 3, 4, ..., 9 天生效。
在第 20 天,你花了 costs[0] = $2 买了一张为期 1 天的通行证,它将在第 20 天生效。
你总共花了 $11,并完成了你计划的每一天旅行。
class Solution {
int min = 0x3f3f3f3f, end, ds[], cs[], a[] = new int[] {1, 7, 30};
boolean[] plan;
void dfs(int cur, int cost) {
if (cur > end) {
min = Math.min(min, cost);
return;
}
for (int i = 0; i < 3; i++) {
if (!plan[cur]) {
dfs(cur+1, cost);
continue;
}
dfs(cur+a[i], cost+cs[i]);
}
}
public int mincostTickets(int[] days, int[] costs) {
this.ds = days; this.cs = costs; this.end = days[days.length-1];
plan = new boolean[366];
for (int d : days) plan[d] = true;
dfs(0, 0);
return min;
}
}
这样做竟然只过了 1/66 样例…,剪下枝吧:
class Solution {
public:
int mi = INT_MAX, plan[367], s[3] = {1, 7, 30};
vector<int> ds, cs;
void dfs(int d, int c, vector<int>& f) {
if (d > ds.back()) {
mi = min(mi, c);
return;
}
if (c > mi)
return;
if (f[d] != 0 && f[d] <= c)
return;
f[d] = c;
for (int i = 0; i < 3; i++) {
if (!plan[d]) dfs(d+1, c, f);
else dfs(d+s[i], c+cs[i], f);
}
}
int mincostTickets(vector<int>& days, vector<int>& costs) {
ds = days; cs = costs;
for (int d : ds) plan[d] = 1;
vector<int> f(ds.back()+5, 0);
dfs(0, 0, f);
return mi;
}
};
嗯,32 ms 效率并不是很高,但可 ac…
class Solution {
public:
int plan[367];
int mincostTickets(vector<int>& ds, vector<int>& cs) {
int d[3] = {1, 7, 30}, n = ds.size(), e = ds[n-1];
for (int i : ds) plan[i] = 1;
vector<int> f(e+5, 0);
for (int i = 1; i <= e; i++) {
if (!plan[i])
f[i] = f[i-1];
else {
int a = f[i-1] + cs[0];
int b = f[max(0, i-7)] + cs[1];
int c = f[max(0, i-30)] + cs[2];
f[i] = min({a, b, c});
}
}
return f[e];
}
};
实在搞不懂为什么 else 里面写循环 for (3) 循环不行的…
int mi = INF;
for (int j = 0; j < 3; j++) if (i-d[j] >= 0) {
mi = min(mi, f[i-d[j]] + cs[j]);
}
f[i] = mi;